【问题标题】:Unable to parse XML using java无法使用 java 解析 XML
【发布时间】:2018-01-22 10:00:02
【问题描述】:

我有一个 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();
    }

【问题讨论】:

  • “无法到达”是什么意思?你尝试了什么?
  • 到目前为止你做了什么?向我们展示您的代码。
  • 请建议。我已经添加了代码。 @GeorgHenkel

标签: java xml parsing xml-parsing


【解决方案1】:

您正在请求一个名为“Remark”的元素,但您的文档不包含这样的元素。相反,它只包含一个带有一堆文本的“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 yeaaaaah!”。

您还有一个有趣的问题:为什么您的服务输出带有 XML 的 XML? XML 本身就已经足够嵌套了。真的有必要将它的一部分包装在 CDATA 中吗?

【讨论】:

  • 谢谢...它成功了。你的问题的答案是它不是我的 XML。我正在使用第三方 API,他们以这种格式响应,所以无论如何我只需要解析这个。
【解决方案2】:

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() 方法获取内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-07
    • 1970-01-01
    • 1970-01-01
    • 2013-01-09
    • 1970-01-01
    • 2013-03-04
    • 1970-01-01
    • 2013-10-25
    相关资源
    最近更新 更多