从XML解析CDATA以启用编辑Java

时间:2014-03-03 16:32:37

标签: java xml parsing cdata

我正在编写一个模拟器,它通过本地套接字与客户端的软件进行通信。通信语言是XML。我编写了一些有用的代码 - 通过DocumentBuilder接口将传入的XML字符串解析为Document。

我遇到过CDATA的问题(之前从未见过)。基本上,我需要访问CDATA标签中的字段并进行更改。我加载一个“模板”XML文档(用于回复消息)并使用响应中第一条消息中收到的值。一些需要更改的字段在此CDATA标记中(清楚我的意思如下)。

public static String getOutputMessage(String input) throws Exception{
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    Document inputDoc, outputDoc;
    Element messageElement = (Element)inputDoc.getElementsByTagName("TRANS").item(0);
    messageType = messageElement.getAttribute("name");
    if (messageType.equals("processTransaction")){
        outputDoc = db.parse(path+"processTransaction\\posPrintReceipt.xml");
        outputDoc = changeContent(outputDoc, "PAN_NUMBER", transaction.getPan_number());
        outputDoc = changeContent(outputDoc, "TOKEN", transaction.getToken());
        outputDoc = changeContent(outputDoc, "TOTAL_AMOUNT", transaction.getTotal_amount());
        outputDoc = changeContent(outputDoc, "TRANSACTION_TIME", transaction.getTransaction_time());
        outputDoc = changeContent(outputDoc, "TRANSACTION_DATE", transaction.getTransaction_date());
    }
}

private static Document changeContent(Document doc,String tag,String value) {
    System.out.println("Changing: ["+tag+" : "+value+"]");
    NodeList nodes=doc.getElementsByTagName(tag);
    Node node = nodes.item(0);
    Node parent=node.getParentNode();
    node.setTextContent(value);
    System.out.println(doc.getElementsByTagName(tag).item(0) + " " + node.getTextContent());
    parent.replaceChild(node, doc.getElementsByTagName(tag).item(0));
    return doc;
}

上述函数适用于普通元素,但下面是我必须阅读并更改某些值的示例XML消息,例如

<RLSOLVE_MSG version="5.0">
<MESSAGE>
    <SOURCE_ID>DP01</SOURCE_ID>
    <TRANS_NUM>000001</TRANS_NUM>
</MESSAGE>
<POI_MSG type="interaction">
    <INTERACTION name="posPrintReceipt">
        <RECEIPT type="merchant" format="xml">
            <![CDATA[<RECEIPT>
    <AUTH_CODE>06130</AUTH_CODE>
    <CARD_SCHEME>VISA</CARD_SCHEME>
    <CURRENCY_CODE>GBP</CURRENCY_CODE>
    <CUSTOMER_PRESENCE>internet</CUSTOMER_PRESENCE>
    <FINAL_AMOUNT>1.00</FINAL_AMOUNT>
    <MERCHANT_NUMBER>8888888</MERCHANT_NUMBER>
    <PAN_NUMBER>454420******0382</PAN_NUMBER>
    <PAN_EXPIRY>12/15</PAN_EXPIRY>
    <TERMINAL_ID>04176421</TERMINAL_ID>
    <TOKEN>454420bbbbbkqrm0382</TOKEN>
    <TOTAL_AMOUNT>1.00</TOTAL_AMOUNT>
    <TRANSACTION_DATA_SOURCE>keyed</TRANSACTION_DATA_SOURCE>
    <TRANSACTION_DATE>14/02/2014</TRANSACTION_DATE>
    <TRANSACTION_NUMBER>000001</TRANSACTION_NUMBER>
    <TRANSACTION_RESPONSE>06130</TRANSACTION_RESPONSE>
    <TRANSACTION_TIME>17:13:17</TRANSACTION_TIME>
    <TRANSACTION_TYPE>purchase</TRANSACTION_TYPE>
    <VERIFICATION_METHOD>unknown</VERIFICATION_METHOD>
    <DUPLICATE>false</DUPLICATE>
</RECEIPT>]]>
        </RECEIPT>
    </INTERACTION>
</POI_MSG>

2 个答案:

答案 0 :(得分:0)

CDATA是一种在XML文件中包含任意数据的编码机制。将XML加载到Document实例时,CDATA中的所有内容都被解析为单个字符串。如果需要将CDATA的内容作为DOM文档访问,则需要从字符串内容中实例化第二个Document对象,进行更改,然后将其序列化为字符串并将字符串放回原始文件中的CDATA。

答案 1 :(得分:0)

我不认为CDATA部分会被解析为XML中的其他常规元素。 CDATA部分纯粹是为了逃避任何语法检查。我的建议是使用一个元素来表示CDATA部分中的数据。如果您仍想使用CDATA部分,我想您需要将该部分解析为字符串,然后将数据加载到Document中。