4

我正在使用 XMLDocument 创建 XML 文件,但是当 XML 节点获取“&”作为数据时,它会转换为“与号(&)amp;” 但我需要'&'的实际值,谁能告诉我如何实现它?

结果:

4

4 回答 4

12

XML 文档中的单个&非法的(在 CDATA 部分之外;请参阅@rsp 的答案),因此这是不可能的。如果节点数据中有逐字与符号,则必须将其编码为&.

但这也没有问题,因为任何 XML 阅读器在解析 XML 文件时都会解码&为文字。&

于 2013-07-02T11:18:10.490 回答
5

如果确实需要在 XML 表示中使用未转义的 & 符号,则可以使用CDATA部分,但会牺牲字符数据的<![CDATA[开头和]]>结尾。

于 2013-07-02T11:28:49.887 回答
2

我曾经遇到过这种情况,我想在 XML 中保留原始 & 符号。尽管您的解析器可能与我的不同(我使用 MarkLogic),但以下内容仍然适用于您使用任何 XML 解析器的情况:

& 字符的问题

    The ampersand character can be tricky to construct in an XQuery string, as it is an escape character to the XQuery parser. The ways to construct the ampersand character in XQuery are:

    Use the XML entity syntax (for example, &amp;).
    Use a CDATA element (<![CDATA[element content here]]>), which tells the XQuery parser to read the content as character data.
    Use the repair option on xdmp:document-load, xdmp:document-get, or xdmp:unquote.
    https://help.marklogic.com/knowledgebase/article/View/55/0/xquery-ampersand-in-string

显然,上面列出的第一个选项,即转义 & 符号,并不是我们想要的方向。我们想要原始的 & 符号,而不是转义的实体。
第二个选项起初似乎是个好主意,我玩了很长时间的 CDATA 元素。CDATA 允许“字符数据”,其中的所有内容都被视为字符数据,而不是真正的 XML。在玩了一些例子之后,我发现你可以让 CDATA 返回 & 符号,但是 CDATA 元素非常不友好。例如,创建动态 CDATA 元素几乎是不可能的,您不能简单地将 XML 结构包装在 CDATA 中。CDATA 意味着其中包含静态的预定义字符。如果有使用 CDATA 的有效方法,我找不到它。Xdmp:quote 和 xdmp:unquote 完成了我们需要的技巧,尽管也不是我们期望的那样。例如:

let $xml := <rootNode title="test"><firstLevel type="crazy"><secondLevel reason="testing">D&amp;C</secondLevel><secondLevel owner="clint">D&amp;C</secondLevel></firstLevel></rootNode>
return xdmp:quote($xml//secondLevel[1])
(: Returns <secondLevel reason="testing">D&amp;C</secondLevel> :)

let $xml := <rootNode title="test"><firstLevel type="crazy"><secondLevel reason="testing">D&amp;C</secondLevel><secondLevel owner="clint">D&amp;C</secondLevel></firstLevel></rootNode>
return xdmp:quote($xml//secondLevel[1]/node())
(: Returns D&C - an unescaped ampersand! :)

第二个示例为我们提供了未转义的 & 符号,但这仅仅是因为我们尝试 xdmp:quote 的对象是文本,而不是元素。在第一个示例中,如果我们尝试引用元素,它将返回 XML 的文本版本,但带有 D&C - 转义的 & 符号。因此,为了让 xdmp:quote 给我们一个带 & 号的字符串,带 & 号的对象必须是独立的文本。
从这里开始,我们可能有几个不同的方向,我的想法肯定不是最优雅或最有效的。但我决定创建一个递归函数,将所有 XML 解析为文本,并允许 xdmp:quote 纯文本作为 & 符号。

declare function local:stringify($xml)
{
  if (xdmp:node-kind($xml) eq "text") then
    xdmp:quote($xml, <options xmlns="xdmp:quote">
                  <method>text</method>
                </options>)
  else if (xdmp:node-kind($xml) eq "element") then
      fn:string-join(
        (fn:concat("<", fn:local-name($xml)),
        for $attr in $xml/@*
          return fn:concat(' ', fn:local-name($attr), '="', $attr, '"'),
        ">",
        for $node in $xml/node()
          return local:stringify($node),
        fn:concat("</", fn:local-name($xml), ">")
      ), "")
  else ()
};

let $xml := <rootNode title="test"><firstLevel type="crazy"><secondLevel reason="testing">D&amp;C</secondLevel><secondLevel owner="clint">D&amp;C</secondLevel></firstLevel></rootNode>


return local:stringify($xml)
(: Returns <rootNode title="test"><firstLevel type="crazy"><secondLevel reason="testing">D&C</secondLevel><secondLevel owner="clint">D&C</secondLevel></firstLevel></rootNode> :)

因此,虽然此解决方案不允许在我们的应用程序中传递的 XML 中存在与号,但它确实允许传递被视为文本的打包 XML。

于 2015-04-17T00:42:48.130 回答
1

我想一个可以使用下面的行。选项 like"repair-full"将仅&作为&

let $InputXML := xdmp:unquote($inputSearchDetails, "", ("format-xml", "repair-full"))

于 2015-04-23T10:36:17.480 回答