2013-02-28 9 views
6

Ich habe versucht, DTD-Entitäten innerhalb meiner App.config zu definieren und zu verwenden. Zum Beispiel:Kann ich DTD-Entitäten in App.config deklarieren und verwenden?

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE configuration [ 
    <!ENTITY dataSource ".\SQLEXPRESS"> 
]> 
<configuration> 
    <appSettings> 
    <add key="FooDataSource" value="&dataSource;" /> 
    </appSettings> 
    <connectionStrings> 
    <add name="Foo" connectionString="Data Source=&dataSource;;Integrated Security=SSPI;" /> 
    </connectionStrings> 
</configuration> 

System.Configuration.ConfigurationManager Mit appSettings oder connectionStrings lesen wird nicht wirft einen Fehler, aber es ist auch nicht die DTD Einheiten lösen.

(Und manchmal wird das Programm überhaupt nicht ausgeführt werden. Ich habe keine Ahnung, warum .NET nur manchmal einen Konfigurationsfehlers beschwert.)

Ist meine Verwendung von DTD falsch oder nicht .NET keine benutzerdefinierten DTD unterstützen Entitäten in App.config?

Antwort

4

System.Configuration einen Standard XmlReaderSettings verwendet, um zu bestimmen, wie die CONFIG-Datei zu lesen. Welche eine ProhibitDtd Eigenschaft hat .

Console.WriteLine(new XmlReaderSettings().ProhibitDtd); 

Ausgang: True

Also das ist eine einfache Erklärung, warum Ihre CONFIG-Datei funktioniert nicht Sie können den Standardwert mit diesem Stück Code sehen. Es gibt keine Möglichkeit, die Einstellung zu überschreiben.

Erklären, warum Ihr Programm Probleme beim Starten hat, erfordert mehr Aufwand. Das erste Mal, dass die Datei gelesen wird, ist sehr früh, bevor die CLR überhaupt gestartet wird. Der Bootstrapper muss die .config-Datei lesen, um festzustellen, welche Version der CLR geladen werden soll. Wichtig ist das Element <requestedRuntime>. Es verwendet keinen vollständig durchgebrannten XML-Parser, es ist ein sehr getrimmter, bei dem alle DTD-Parsing-Bits entfernt sind. Sie können es sehen, indem Sie SSCLI20 herunterladen, der XML-Parser wird im Unterverzeichnis clr/src/xmlparser gespeichert. Was genau schief gehen könnte, ist nicht so klar, aber wenn dieser Parser Probleme mit der .config-Datei hat, werden Sie nicht herausfinden, was das Problem sein könnte. Dies geschieht viel zu früh, um vernünftige Diagnosen erstellen zu können. Überprüfen Sie das Ausgabefenster auf eine mögliche Exit-Codenummer, die einen Hinweis gibt.

+0

Ausgezeichnete Antwort! Sorry für diesen sinnlosen Kommentar, aber ich musste dir Kudos geben :) – MetaFight

1

Ihre Verwendung der Entität ist korrekt; Das ist wohlgeformtes XML und es sollte kein Problem geben, wenn man die Attributreferenz in den Attributen verwendet.

Es muss etwas mit .NET * sein (was ich nicht kenne).

Um zu zeigen, dass das Unternehmen richtig ist, hier ist Ihre XML durch eine XSLT-Identität übergeben Transformation, die die Entitäten aufgelöst:

XML-Eingabe

<!DOCTYPE configuration [ 
    <!ENTITY dataSource ".\SQLEXPRESS"> 
]> 
<configuration> 
    <appSettings> 
    <add key="FooDataSource" value="&dataSource;" /> 
    </appSettings> 
    <connectionStrings> 
    <add name="Foo" connectionString="Data Source=&dataSource;;Integrated Security=SSPI;" /> 
    </connectionStrings> 
</configuration> 

XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

XML-Ausgabe

<configuration> 
    <appSettings> 
     <add key="FooDataSource" value=".\SQLEXPRESS"/> 
    </appSettings> 
    <connectionStrings> 
     <add name="Foo" 
      connectionString="Data Source=.\SQLEXPRESS;Integrated Security=SSPI;"/> 
    </connectionStrings> 
</configuration> 

* Hier sind ein paar Links, die ich erwähnen, dass andere fanden nicht in der Lage XML-Entitäten an die Arbeit:

1

Reflector (auf .NET 4.0) sagt, dass System.Configuration.ConfigXmlReader (internal ist, versiegelt) verwendet, um Konfigurationsdaten zu lesen, die auf System.Xml.XmlTextReader basiert und es ist Konstruktor XmlTextReader(TextReader input), der internal XmlTextReaderImpl(TextReader input), und dieser Konstruktor ruft this(string.Empty, input, new NameTable()) die this(nt) ruft schafft Aufruf (mit Nametable nur), die als this.entityHandling = EntityHandling.ExpandCharEntities;

privates Feld initialisiert MSDN says die ExpandCharEntities:

erweitert Zeichenentitäten und gibt allgemeine Entitäten als EntityReference Knoten.

So sieht es aus, dass Sie nicht Ihre eigenen Einheiten in CONFIG-Datei verwenden können :(