我该如何解析CDATA?

时间:2014-08-30 21:50:29

标签: java xml parsing xslt xpath

如何找到并遍历CDATA下的所有节点,这些节点由(<)启动并由(>)关闭?

另外,我应该如何遍历所有子节点并获取下面子节点中的值?我想要检索该值。

输入XML

    <SOURCE TransactionId="1" ProviderName="ABCDD"><RESPONSE><![CDATA[<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><NetworkResponse xmlns="http://www.example.com/"><NetworkResult>&lt;Network offering_id="13" transaction_id="2" submission_id="3" timestamp="20140828  16010683 GMT" customer_id="NETTest"&gt;
        &lt;Network_List&gt;
            &lt;Network_Info att0="Y" att1="N" att2="N" att3="Y" att4="Y"&gt;
            &lt;SIM_DATA&gt;
                    &lt;SIM&gt;&lt;![CDATA[1100040101]]&gt;&lt;/SIM&gt;
    &lt;/SIM_DATA&gt;
    &lt;NetworkResponseInfo k_status="C"&gt;
                    &lt;KEY1&gt;269&lt;/KEY1&gt;
                    &lt;PARENTNODE&gt;
                        &lt;CHILDNODE1&gt;
                            &lt;KEY2&gt;XXXXXXX&lt;/KEY2&gt;
                            &lt;KEY3&gt;YYYYYYY&lt;/KEY3&gt;
                        &lt;/CHILDNODE1&gt;
                        &lt;CHILDNODE2&gt;
                            &lt;KEY4&gt;N&lt;/KEY4&gt;
                            &lt;KEY5&gt;I&lt;/KEY5&gt;
                        &lt;/CHILDNODE2&gt;
                        &lt;CHILDNODE3&gt;
                            &lt;KEY6&gt;1&lt;/KEY6&gt;
                            &lt;KEY7&gt;3&lt;/KEY7&gt;
                        &lt;/CHILDNODE3&gt;
                    &lt;/PARENTNODE&gt;
                        &lt;KEY8&gt;&lt;![CDATA[some image not visible]]&gt;&lt;/KEY8&gt;
                        &lt;KEY9&gt;N&lt;/KEY9&gt;
                        &lt;KEY10&gt;15&lt;/KEY10&gt;
                &lt;/NetworkResponseInfo&gt;
            &lt;/Network_Info&gt;
        &lt;/Network_List&gt;
        &lt;response_message_list transaction_status_code="000" transaction_status_text="Successful"/&gt;
    &lt;/Network&gt;</NetworkResult></NetworkResponse></soap:Body></soap:Envelope>]]></RESPONSE></SOURCE>

输出XML

                <ns3:NetworkResponse>
                            <Networks_OF_List>
                                <NetCharSeq>
                                    <Nrep>
                                        <type>Some Image</type>
                                        <data>  Data Coming from KEY8 CDATA section</data>
                                    </Nrep>
                                    <Nrep>
                                        <type>ANYTHING</type>
                                        <data>VALUE INSIDE SIM CDATA</data>
                                    </Nrep>
                                    <NetDetail>
                                        <MYKEY1>Value present inside KEY4</MYKEY1>
                                        <MYKEY2>Value present inside KEY5</MYKEY2>
                                    </NetDetail>
                                    <SystemID>Value of KEY2</SystemID>
                                    <SystemPath>Valuelue of KEY3</SystemPath>
                                </NetCharSeq>
                            </Networks_OF_List>
                        </ns3:NetworkResponse>

1 个答案:

答案 0 :(得分:0)

(欢迎来到SO。请注意,由于您没有显示到目前为止所执行的操作,因此您被某些用户拒绝了。请查看How To Ask部分以了解如何提出实际可能存在的问题回答并被认为是SO格式的正确问题。)

如果您可以使用XSLT 3.0,则可以考虑使用新的fn:parse-xml函数,该函数将采用文档作为字符串。

但是,您的CDATA部分包含自己的转义数据,这意味着,在您应用fn:parse-xml之后,您将不得不再次为NetworkResult的子节点文本节点执行此操作。

更好的解决方案通常是在源头修复此问题,并创建一种XML格式,允许某些元素中的其他XML(您可以使用正确的XSD进行此操作)。它将为您节省很多麻烦,至少您可以预先验证XML。

如果你坚持使用XSLT 2.0或1.0,你可以使用disable-output-escaping(google it,有很多关于如何使用它的信息),但你必须重新处理输出一次更多是因为使用了双重逃逸。您可能需要考虑使用XProc pipeline来简化流程。

  

您写道:此外,我应该如何遍历所有子节点并获取下面子节点中的值

这就是XSLT的全部内容,请阅读此XSLT Tutorial或您可以找到的任何其他教程,它将在头几分钟向您解释。

更新:根据评论中michael.hor257k的建议,您还可以使用字符串操作函数手动解析转义数据。正如他在评论中已经说过的那样,这很费力且容易出错,但有时也是如此。如果在unescaping之后XML不是真正的XML,而是之类的 XML,那么这可能是你唯一的选择。