2013-02-28 70 views
6

我试图在我的App.config中定义和使用DTD实体。例如:我可以在App.config中声明和使用DTD实体吗?

<?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阅读appSettingsconnectionStrings不会引发错误,但它也不能解决DTD实体。

(有时程序将不会执行的。我不知道为什么.NET抱怨只是偶尔出现配置错误。)

是我使用DTD的不正确或不.NET不支持自定义DTD App.config的实体吗?

回答

4

System.Configuration使用默认XmlReaderSettings以确定如何读取config文件使用自己的实体。其中有一个ProhibitDtd属性。你可以看到它的默认值与该位的代码:

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

输出:真

所以这是一个简单的解释,为什么你的config文件不起作用。没有办法配置它来覆盖设置。

解释为什么你的程序启动困难需要更多的努力。在CLR开始之前,文件首次被读取的时间很早。引导程序需要读取.config文件以确定要加载哪个版本的CLR,因此<requestedRuntime>元素很重要。它没有使用完整的XML解析器,它是一个非常精细的解析器,它除去了所有的DTD解析位。您可以通过下载SSCLI20来查看它,XML解析器存储在clr/src/xmlparser子目录中。确切地说,可能会出现什么问题并不明显,但是如果该解析器对.config文件有任何问题,那么您将无法找出问题所在。发生这种情况的方式太早,无法生成任何合理的诊断信息。检查输出窗口中是否有可能提供提示的退出代码。

+0

优秀的答案!对于这个毫无意义的评论感到抱歉,但我不得不赞扬你:) – MetaFight 2014-07-29 11:15:17

1

您对实体的使用是正确的;这是格式良好的XML,在属性中使用属性引用不应该有任何问题。

它必须是.NET *(我不知道)的东西。

为了证明实体是正确的,这里是你的XML通过XSLT身份通过变换它解决了实体:

XML输入

<!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输出

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

*以下是我发现,提到别人不能够得到几个环节XML实体合作:

1

反射器(在.NET 4.0上)说System.Configuration.ConfigXmlReader(内部,密封)用于读取配置数据,这是基于System.Xml.XmlTextReader,把它的构造XmlTextReader(TextReader input),谁创造internal XmlTextReaderImpl(TextReader input),而这个构造函数调用this(string.Empty, input, new NameTable())这就要求this(nt)(只有NameTable)的初始化私有字段为this.entityHandling = EntityHandling.ExpandCharEntities;

MSDN says是ExpandCharEntities:

扩展字符实体,并返回一般实体 EntityReference节点。

所以看起来,你不能在config文件:(

相关问题