强制将 XML 字符实体放入 XmlDocument 中

发布于 2024-09-18 22:07:27 字数 958 浏览 2 评论 0原文

我有一些看起来像这样的 XML:

<abc x="{"></abc>

我想强制 XmlDocument 使用括号的 XML 字符实体,即:

<abc x="&#123;"></abc>

MSDN 是这样说的:

为了分配属性值 包含实体引用, 用户必须创建一个 XmlAttribute 节点 加上任何 XmlText 和 XmlEntityReference 节点,构建 适当的子树和使用 SetAttributeNode 将其指定为 属性的值。

CreateEntityReference 听起来很有希望,所以我尝试了这个:

XmlDocument doc = new XmlDocument();
doc.LoadXml("<abc />");
XmlAttribute x = doc.CreateAttribute("x");
x.AppendChild(doc.CreateEntityReference("#123"));
doc.DocumentElement.Attributes.Append(x);

我得到异常无法创建名称以“#”开头的“EntityReference”节点。

CreateEntityReference 不喜欢“#”的任何原因 - 更重要的是我怎样才能获得字符实体到 XmlDocument 的 XML 中?有可能吗?我希望避免 OuterXml 的字符串操作...

I have some XML that looks like this:

<abc x="{"></abc>

I want to force XmlDocument to use the XML character entities of the brackets, ie:

<abc x="{"></abc>

MSDN says this:

In order to assign an attribute value
that contains entity references, the
user must create an XmlAttribute node
plus any XmlText and
XmlEntityReference nodes, build the
appropriate subtree and use
SetAttributeNode to assign it as the
value of an attribute.

CreateEntityReference sounded promising, so I tried this:

XmlDocument doc = new XmlDocument();
doc.LoadXml("<abc />");
XmlAttribute x = doc.CreateAttribute("x");
x.AppendChild(doc.CreateEntityReference("#123"));
doc.DocumentElement.Attributes.Append(x);

And I get the exception Cannot create an 'EntityReference' node with a name starting with '#'.

Any reason why CreateEntityReference doesn't like the '#' - and more importantly how can I get the character entity into XmlDocument's XML? Is it even possible? I'm hoping to avoid string manipulation of the OuterXml...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烟雨凡馨 2024-09-25 22:07:28

你大多不走运。

首先,您正在处理的内容称为字符引用,这就是 CreateEntityReference 失败的原因。字符引用存在的唯一原因是提供对给定上下文中非法或难以创建的字符的访问。

定义:字符引用
指的是一个特定的字符
ISO/IEC 10646 字符集,用于
示例一不可直接访问
从可用的输入设备。

请参阅 XML 规范第 4.1 节

当 XML 处理器遇到字符引用,如果在属性值中引用它(即,如果属性内部使用 &#xxx 格式),则将其设置为“包含”,这意味着其查找值并替换文本。

字符串“AT&T;”扩展为“
AT&T;”,剩下的 & 符号是
不被识别为实体引用
分隔符

请参阅 XML 规范的第 4.4 节)。

( XML 规范和 Microsoft XML 堆栈正在执行其需要执行的操作:处理字符引用。

我能看到您做的最好的事情就是看一下这些旧的 XML.com 文章,其中一篇使用 XSL 来禁用输出转义,因此 { 将变成 输出中的 {
http://www.xml.com/pub/a/ 2001/03/14/trxml10.html

<!DOCTYPE stylesheet [
<!ENTITY ntilde 
"<xsl:text disable-output-escaping='yes'>&ntilde;</xsl:text>">
]>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     version="1.0">

  <xsl:output doctype-system="testOut.dtd"/>

  <xsl:template match="test">
    <testOut>
      The Spanish word for "Spain" is "España".
      <xsl:apply-templates/>
    </testOut>
  </xsl:template>

</xsl:stylesheet>

这个使用 XSL 将特定字符引用转换为其他文本序列(以实现与上一个链接相同的目标)。
http://www.xml.com/lpt/a/1426

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="2.0">

  <xsl:output use-character-maps="cm1"/>

  <xsl:character-map name="cm1">
    <xsl:output-character character=" " string="&nbsp;"/>   
    <xsl:output-character character="é" string="&233;"/> <!-- é -->
    <xsl:output-character character="ô" string="&#244;"/>
    <xsl:output-character character="—" string="--"/>
  </xsl:character-map>

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

</xsl:stylesheet>

You're mostly out of luck.

First off, what you're dealing with are called Character References, which is why CreateEntityReference fails. The sole reason for a character reference to exist is to provide access to characters that would be illegal in a given context or otherwise difficult to create.

Definition: A character reference
refers to a specific character in the
ISO/IEC 10646 character set, for
example one not directly accessible
from available input devices.

(See section 4.1 of the XML spec)

When an XML processor encounters a character reference, if it is referenced in the value of an attribute (that is, if the &#xxx format is used inside an attribute), it is set to "Included" which means its value is looked up and the text is replaced.

The string "AT&T;" expands to "
AT&T;" and the remaining ampersand is
not recognized as an entity-reference
delimiter

(See section 4.4 of the XML spec)

This is baked into the XML spec and the Microsoft XML stack is doing what it's required to do: process character references.

The best I can see you doing is to take a peek at these old XML.com articles, one of which uses XSL to disable output escaping so &#123; would turn into { in the output.
http://www.xml.com/pub/a/2001/03/14/trxml10.html

<!DOCTYPE stylesheet [
<!ENTITY ntilde 
"<xsl:text disable-output-escaping='yes'>&ntilde;</xsl:text>">
]>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     version="1.0">

  <xsl:output doctype-system="testOut.dtd"/>

  <xsl:template match="test">
    <testOut>
      The Spanish word for "Spain" is "España".
      <xsl:apply-templates/>
    </testOut>
  </xsl:template>

</xsl:stylesheet>

And this one which uses XSL to convert specific character references into other text sequences (to accomplish the same goal as the previous link).
http://www.xml.com/lpt/a/1426

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="2.0">

  <xsl:output use-character-maps="cm1"/>

  <xsl:character-map name="cm1">
    <xsl:output-character character=" " string="&nbsp;"/>   
    <xsl:output-character character="é" string="&233;"/> <!-- é -->
    <xsl:output-character character="ô" string="&#244;"/>
    <xsl:output-character character="—" string="--"/>
  </xsl:character-map>

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

</xsl:stylesheet>
薄情伤 2024-09-25 22:07:28

您应该始终使用前面的 @ 来操作字符串,例如 @"My /?.,<> STRING"。我不知道这是否能解决你的问题。
我将使用 XmlDocument 中的 XmlNode 类来解决该问题。您可以使用 Attributes 属性,这会更容易。在这里查看:
http://msdn.microsoft.com/en-我们/library/system.xml.xmlnode.attributes.aspx

You should always manipulate your strings with the preceding @ like so @"My /?.,<> STRING". I don't know if that will solve your issue though.
I would approach the problem using XmlNode class from the XmlDocument. You can use the Attributes property and it'll be way easier. Check it out here:
http://msdn.microsoft.com/en-us/library/system.xml.xmlnode.attributes.aspx

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文