无法使用java解析XML

时间:2018-01-22 10:00:03

标签: java xml parsing xml-parsing

我有一个XML字符串作为响应。但我无法联系响应代码并发表评论。任何人都可以帮我获取响应代码。

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <GetIMEIInfoResponse xmlns="http://tempuri.org/">
      <GetIMEIInfoResult>
        <![CDATA[
        <SerialsDetail>
          <Item>
            <ResponseCode>2</ResponseCode>
            <Remark>Invalid Input</Remark>
          </Item>
        </SerialsDetail>
        ]]>
      </GetIMEIInfoResult>
    </GetIMEIInfoResponse>
  </s:Body>
</s:Envelope>

这就是我要做的事情

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder;
    try {
        builder = factory.newDocumentBuilder();
        Document doc = builder.parse(new InputSource(new StringReader(response)));
        NodeList list = doc.getElementsByTagName("Remark");
        System.out.println(list.getLength());
        Node n = list.item(0);
        System.out.println(n.getTextContent());
    } catch (Exception e) {
        e.printStackTrace();
    }

2 个答案:

答案 0 :(得分:1)

您要求的名称为“备注”的元素,但您的文档不包含此类元素。相反,它只包含一个“GetIMEIInfoResult”元素,其中包含一堆文本。这个文本恰好是xml。但是为了访问内部XML的内容,您必须以解析整个文档的方式解析“GetIMEIInfoResult”的内容。

以下是如何做到这一点:

import java.io.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.InputSource;

public class NestedCDATA {

    private static String response = 
        "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
        "  <s:Body>" +
        "    <GetIMEIInfoResponse xmlns=\"http://tempuri.org/\">" +
        "      <GetIMEIInfoResult>" +
        "        <![CDATA[" +
        "        <SerialsDetail>" +
        "          <Item>" +
        "            <ResponseCode>2</ResponseCode>" +
        "            <Remark>Aawwwwwwww yeaaaah!</Remark>" +
        "          </Item>" +
        "        </SerialsDetail>" +
        "        ]]>" +
        "      </GetIMEIInfoResult>" +
        "    </GetIMEIInfoResponse>" +
        "  </s:Body>" +
        "</s:Envelope>";

    public static String getCdata(Node parent) {
        NodeList cs = parent.getChildNodes();
        for(int i = 0; i < cs.getLength(); i++){
            Node c = cs.item(i);
            if(c instanceof CharacterData) {
                CharacterData cdata = (CharacterData)c;
                String content = cdata.getData().trim();
                if (content.length() > 0) {
                  return content;
                }
            }
        }
        return "";
    }


    public static void main(String[] args) {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder;
        try {
            builder = factory.newDocumentBuilder();
            Document doc = builder.parse(new InputSource(new StringReader(response)));
            Node cdataParent = doc.getElementsByTagName("GetIMEIInfoResult").item(0);
            DocumentBuilder cdataBuilder = factory.newDocumentBuilder();
            Document cdataDoc = cdataBuilder.parse(new InputSource(new StringReader(
              getCdata(cdataParent)
            )));
            Node remark = cdataDoc.getElementsByTagName("Remark").item(0);
            System.out.println("Content of Remark in CDATA: " + getCdata(remark));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

结果:“CDATA备注内容:Aawwwwwwww yeaaaah!”。

这是另一个有趣的问题:为什么你的服务输出带有XML的XML? XML本身已经足够嵌套了。是否真的有必要将其中的部分内容包装在CDATA中?

答案 1 :(得分:0)

XML的问题是标记GetIMEIInfoResult中的数据是CDATA。这会导致构建器不将其识别为XML。要访问代码GetIMEIInfoResult中的数据,您可以使用以下内容:

Element infoResult = (Element) list.item(0);
String elementData = getCharacterDataOfNode(infoResult.getFirstChild());

public static String getCharacterDataOfNode(Node node) {
    String data = "";
    if (node instanceof CharacterData) {
        data = ((CharacterData) node).getData();
    }
    return data;
}

然后,您必须使用DocumentBuilder再次解析该数据,您可以在其中访问代码Remark。要获取您再次使用getCharacterDataOfNode()方法的内容。