带有嵌套CDATA部分的lxml

时间:2013-02-19 20:41:02

标签: xml lxml cdata

我有XML(在别处生成,无法控制),其中包含令人讨厌的嵌套CDATA,例如:

<?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。写我自己的解析器?想法?

2 个答案:

答案 0 :(得分: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解析器。

答案 1 :(得分:1)

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

CDATA部分可能不包含“]]&gt;”。在XML中转义它的正确方法就是这个“]]]]&gt;”

See this question for more detail