如何解析XML的<![CDATA[]]>部分

9
如何解析包含在<![CDATA[---]...中的数据的XML?我们如何解析XML并获取包含在CDATA中的数据?

你是通过手动解析文件还是使用XMLReader类(如果使用,是哪个版本)来解析文件的? - Thargor
5个回答

9
public static void main(String[] args) throws Exception {
  File file = new File("data.xml");
  DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
 //if you are using this code for blackberry xml parsing
  builder.setCoalescing(true);
  Document doc = builder.parse(file);

  NodeList nodes = doc.getElementsByTagName("topic");
  for (int i = 0; i < nodes.getLength(); i++) {
    Element element = (Element) nodes.item(i);
    NodeList title = element.getElementsByTagName("title");
    Element line = (Element) title.item(0);
    System.out.println("Title: " + getCharacterDataFromElement(line));
  }
}
public static String getCharacterDataFromElement(Element e) {
  Node child = e.getFirstChild();
  if (child instanceof CharacterData) {
    CharacterData cd = (CharacterData) child;
    return cd.getData();
  }
  return "";
}

(http://www.java2s.com/Code/Java/XML/GetcharacterdataCDATAfromxmldocument.htm)

这个链接是关于从XML文档中获取字符数据和CDATA的Java代码示例。

我更倾向于这样做: 如果(child != null && (child instanceof CharacterData)) { return ((CharacterData) child).getData(); } else { return e.getNodeValue(); } 以便无缝处理CDATA块的存在/不存在。 - Raphael Jolivet
请提供一些文本来描述您正在做什么以及为什么要使用DocumentBuilderFactory - Gray
在当前的Java DOM实现中,您可以使用e.getTextContent()简单地访问CDATA作为文本数据。请参见示例,无需类型检查、强制转换或e.getData() - jschnasse

4

由于所有之前的答案都采用基于 DOM 的方法。这是使用基于 STAX 的流式方法解析 CDATA 的方式。

使用以下模式:

  switch (EventType) {
        case XMLStreamConstants.CHARACTERS:
        case XMLStreamConstants.CDATA:
            System.out.println(r.getText());
            break;
        default:
            break;
        }

完整示例:
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamReader;

public void readCDATAFromXMLUsingStax() {
    String yourSampleFile = "/path/toYour/sample/file.xml";
    XMLStreamReader r = null;
    try (InputStream in =
            new BufferedInputStream(new FileInputStream(yourSampleFile));) {
        XMLInputFactory factory = XMLInputFactory.newInstance();
        r = factory.createXMLStreamReader(in);
        while (r.hasNext()) {
            switch (r.getEventType()) {
            case XMLStreamConstants.CHARACTERS:
            case XMLStreamConstants.CDATA:
                System.out.println(r.getText());
                break;
            default:
                break;
            }
            r.next();
        }
    } catch (Exception e) {
        throw new RuntimeException(e);
    } finally {
        if (r != null) {
            try {
                r.close();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
}

使用 /path/toYour/sample/file.xml

 <data>
    <![CDATA[ Sat Nov 19 18:50:15 2016 (1672822)]]>
    <![CDATA[Sat, 19 Nov 2016 18:50:14 -0800 (PST)]]>
 </data>

给出:

 Sat Nov 19 18:50:15 2016 (1672822)                             
 Sat, 19 Nov 2016 18:50:14 -0800 (PST)       

2

CDATA 只是表示包含的数据不应该被转义,所以只需获取标记文本。XML解析器应该返回没有 CDATA 的清晰数据。


1
获取文本数据:e.getTextContent(); - Ariel T

0
以下是示例XML文件和检索嵌入在主XML中的CDATA的代码。
<envelope>
 <Header>
  <id>123</id>
  <name>abc</name>
 </Header>
 <payload>
  <![CDATA[<?xml> <Document><validXML></validXML></Document>]]>
</payload>
</envelope>

获取上述示例中的CDATA XML的Xpath将是:
/envelope/payload/text()

因此,一旦您拥有上述xml的根文档,并具有给定路径,您可以获取嵌入在CDATA中的xml。

以下是相应的实用方法。

public String getSubDocument(Document rootDocument, String xPathString) throws Exception {
XPath xPath = XPathFactory.newInstance().newXPath();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document rootDoc = builder.newDocument();
String xmlString = (String)xPath.compile(xPathString).evaluate(rootDocument, XPathConstants.String);
return xmlString;
}

}


0

这里 r.get().getResponseBody() 是响应体

Document doc = getDomElement(r.get().getResponseBody());            
    NodeList nodes = doc.getElementsByTagName("Title");
    for (int i = 0; i < nodes.getLength(); i++) {
    Element element = (Element) nodes.item(i);
    NodeList title = element.getElementsByTagName("Child tag where cdata present");
    Element line = (Element) title.item(0);
    System.out.println("Title: "+ getCharacterDataFromElement(line));


    public static Document getDomElement(String xml) {
        Document doc = null;
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setCoalescing(true);
        dbf.setNamespaceAware(true);
        try {
            DocumentBuilder db = dbf.newDocumentBuilder();
            InputSource is = new InputSource();
            is.setCharacterStream(new StringReader(xml));
            doc = db.parse(is);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return doc;
    }

    public static String getCharacterDataFromElement(Element e) {
        Node child = e.getFirstChild();
        if (child instanceof CharacterData) {
            CharacterData cd = (CharacterData) child;
            return cd.getData();
        }
        return "";
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接