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