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 に答える