0

我有包含讨厌的嵌套 CDATA 的 XML(在其他地方生成,无法控制),例如:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE prc SYSTEM "prc.dtd">
<body>
  <![CDATA[Towards Automatic Generation blabla
<definition> 
   <query><![CDATA[ <root[AByS]> <sc methodName="get_NYT.ARTICLES" serviceURL="http://www.nytimes.com/srv/"> 
  <params> <param name="subjectP" value="{ subjectP }"> </> </> </> <sc methodName="get_WP.ARTICLES" 
   serviceURL="http://www.wpost.com/srv/"> <params> <param name="subjectP" value="{ subjectP }"> </> </> 
   </> </>; ]]></query> </definition> </serviceDefinition> (b) Figure 7. (a) The query for Web service 
]]>
</body>

lxml(Python)炸弹

XMLSyntaxError: Opening and ending tag mismatch: body line 3 and query, line 9, column 28

因为它认为第一个]]>结束 CDATA,而实际上它只结束内部 CDATA,而后面的标签 ,</query>仍然在外部 CDATA 内,不应该被解析。

什么是解析此类 XML 的好方法?这意味着我希望 CDATA 中的所有内容都保留为未解析的数据,即使它内部包含更多 CDATA。写我自己的解析器?想法?

4

2 回答 2

2

由于嵌套CDATA部分使其不是来自良好的 XML,因此您不能在其上使用任何 XML 工具。

您需要使用可以处理嵌套结构的文本解析器,因此它需要计数器或堆栈支持。这排除了简单的正则表达式解决方案。如果这些CDATA部分是平衡的,则该任务在某种程度上类似于处理嵌套括号。

展开嵌套CDATA部分的一种方法是使它们成为连续CDATA部分。

一些伪代码:

counter = 0 or stack is empty
when found "<![CDATA[" string
    if counter != 0 or stack not empty
        replace "<![CDATA[" with "]]><![CDATA["
    increase counter or push to stack
when found "]]>" string
    decrease counter or pop stack
    if counter != 0 or stack not empty
        replace "]]>" with "]]><![CDATA["

理想情况下,您可以将其用作输入流阅读器,将输出通过管道传输到 XML 解析器。

于 2013-02-20T01:16:21.463 回答
1

嵌套 CDATA 不合法,因此这不是有效的 XML。

CDATA 部分可能不包含“]]>”。在 XML 中转义它的正确方法是这样的 "]]]]>"

有关更多详细信息,请参阅此问题

于 2013-02-19T20:59:40.110 回答