我有问题。我有几个xml文件随机包含其中包含CDATA和reqular xml节点的节点。我需要读取这些节点的内容,但不确定如何确定节点是正常的xml节点,CDATA节点还是包含两者的混合的节点,其中开头和结尾的CDATA部分可以包含任何东西。 (我正在使用xPath引用我的节点,如果有帮助的话)
用于检索节点文本内容的行:
contentObj.text = contentNode.selectSingleNode("./text").text;
导致问题的xml示例:
<text>
<![CDATA[<P align=center> </P>
<P align=center>]]>
<media identifier="005896523">
<label>
<![CDATA[NOTE]]>
</label>
<description>
<![CDATA[Image for NOTE]]>
</description>
<comments>Update Required</comments>
</media>
<![CDATA[</P>
<P> </P>
<P align=left> </P>]]>
</text>
答案 0 :(得分:0)
当你说
时contentNode.selectSingleNode("./text")
这当然返回<text>
元素节点;但是当你再要求
.text
它的属性,你要求整个<text>
元素的文本内容,它是所有后代文本节点的值的串联。
如果要选择单个文本节点,请尝试
contentNode.selectSingleNode("./text/text()[1]").text;
即。选择<text>
元素的第一个文本节点子节点,然后检索其text属性。这应该会在您的示例中为您提供"<P align=center> </P> <P align=center>"
(作为未解析的文本,而不是XML树)。
为了区分CDATA和非CDATA,您必须解决XPath问题,而XPath并不是为了能够区分它们而设计的。另一方面,XML DOM至少在某些实现中可以。所以你可以尝试
var children = contentNode.selectNodes("./text/node()");
将选择nodeList
元素的所有子元素的<text>
,包括文本节点,元素节点和可能的CDATA节点。遍历children
中的节点并检查其nodeType
属性,看看它是NODE_CDATA_SECTION
,NODE_TEXT
还是别的。
让我们知道它是怎么回事,以及您是否需要进一步的帮助。
我假设你接受了这个答案,你能够让事情发挥作用,我很高兴你能够做到。
但是,我不想在不强调@choroba暗示的警告的情况下放弃这一点:大多数XML工具都看不到CDATA包装器(大约一大块文本)(尽管文本内容是可见的)。 XML数据模型(非正式地描述here)对CDATA部分一无所知。关于CDATA标记部分边界的XML Infoset explicitly omits标准。
所以,虽然这次你“幸运”,因为你使用的XML DOM确实提供了有关CDATA部分的信息,但是依靠这些信息来编码重要数据违背了XML的精神(因此是不明智的)在XML中。出于这个原因,您可以通过其他方式对该信息进行编码。否则,如果您需要在数据上使用其他XML工具,则可能会卡住。
我认为您在此处尝试提取的重要信息是CDATA部分中的文本是转义标记。例如。它是不应该(或不能)成为XML树的一部分的HTML标记。因此,您可以通过使用自定义元素包围每个标识来对该标识进行编码:
<text>
<escaped><![CDATA[<P align=center> </P>
<P align=center>]]></escaped>
<media identifier="005896523">
...
然后,为了将来找到这些部分,您所要做的就是查找名为<escaped>
的元素,这对任何XML工具来说都是一项简单而自然的任务。
我不知道这些XML文件的设计是否在您的控制之下。如果没有,您至少应该可以选择向设计师发送反馈。如果一个不精通XML事物的设计师犯了设计错误,那么了解它就符合他们的最佳利益,这样他们就可以纠正它,或者至少避免在未来的设计中犯同样的错误。如果您在一个命令链下工作,并且XML的设计者在不同的部门,那么反馈的适当途径可能是通过您的主管。了解他们是否正在制作非便携式XML设计符合该部门的最佳利益。