如何解决XML中的&符号(&)转换问题?

时间:2013-07-02 10:42:37

标签: xml

我正在使用XMLDocument创建XML文件,但是当XML节点获得'&'时作为数据,它在“&符号(&)放大器”中转换但我需要实际价值'和',任何人都可以告诉我如何实现它?

结果:

4 个答案:

答案 0 :(得分:7)

XML文档中的单个& 非法(CDATA部分之外;请参阅@ rsp的答案),因此无法做到这一点。如果您的节点数据中有逐字符号&符号,则 将被编码为&

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

答案 1 :(得分:3)

如果确实需要在XML表示中使用未转义的&符号,则可以使用CDATA部分,费用为<![CDATA[开头,]]>结束字符数据。< / p>

答案 2 :(得分: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&amp; C - 转义的&符号。因此,为了让xdmp:quote为我们提供一个带&符号的字符串,带有&符号的对象必须是独立文本。
从这里开始,我们可能会有一些不同的方向,我的想法肯定不是最优雅或最有效的。但我决定创建一个递归函数,将所有XML解析为文本,并允许使用xdmp:纯文本引用&符号。

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。

答案 3 :(得分:1)

我想可以使用下面一行。 像"repair-full"这样的选项只会将&作为&

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

相关问题