7

我试图在我的App.config. 例如:

<?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

3 回答 3

4

System.Configuration 使用默认的 XmlReaderSettings 来确定如何读取 .config 文件。其中有一个 ProhibitDtd 属性。您可以使用以下代码查看其默认值:

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

输出:真

这就是为什么您的 .config 文件不起作用的简单解释。没有任何方法可以将其配置为覆盖设置。

解释程序启动困难的原因需要更多的努力。第一次读取文件的时间很早,甚至在 CLR 启动之前。引导程序需要读取 .config 文件以确定要加载的 CLR 版本,该<requestedRuntime>元素很重要。它没有使用成熟的 XML 解析器,它是一个非常精简的解析器,删除了所有 DTD 解析位。下载SSCLI20可以看到,XML解析器存放在clr/src/xmlparser子目录下。究竟什么可能出错并不清楚,但如果该解析器对 .config 文件有任何问题,那么您将不会找出问题可能是什么。这种情况发生得太早,无法生成任何合理的诊断。检查“输出”窗口以获取提供提示的可能退出代码号。

于 2013-03-15T21:14:24.273 回答
1

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

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

为了证明实体是正确的,下面是通过解析实体的 XSLT 身份转换传递的 XML:

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 实体工作:

于 2013-03-09T16:51:10.190 回答
1

Reflector(在.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;

MSDNExpandCharEntities:

扩展字符实体并将一般实体作为 EntityReference 节点返回。

所以看起来你不能在 .config 文件中使用你自己的实体:(

于 2013-03-15T10:24:29.233 回答