2013-02-19 85 views
0

我有XML(在别处产生的,在其上没有控制),其含有讨厌嵌套CDATA,诸如例如:LXML嵌套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

由于筑巢CDATA部,也没有很好fromed 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

嵌套的CDATA不合法,所以这不是合法的XML。

CDATA部分可能不包含“]]>”。逃脱它在XML的正确方法是像它这样“]]]]>”

See this question for more detail

+0

嗯,我没有看到这样的转义如何工作......也不知道这些信息如何帮助我解析畸形的XML,即使它工作。 – user124114 2013-02-19 21:38:23