如何为 <![CDATA[]]> 解析 XML
Posted
技术标签:
【中文标题】如何为 <![CDATA[]]> 解析 XML【英文标题】:How to parse XML for <![CDATA[]]> 【发布时间】:2012-01-19 07:44:38 【问题描述】:如何解析包含在<![CDATA[---]...
中的数据的XML 我们如何解析xml 并获取包含在CDATA
中的数据???
【问题讨论】:
您是“手动”解析文件还是使用任何 XMLReader 类(以及哪个类)? 【参考方案1】: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)
【讨论】:
我宁愿做这样的事情: if (child != null && (child instanceof CharacterData)) return ((CharacterData) child).getData(); else 返回 e.getNodeValue();为了无缝处理 CDATA 块的存在/不存在。 您能否提供一些文字来描述您在做什么以及为什么要使用DocumentBuilderFactory
?
在当前的 Java DOM 实现中,您可以使用 e.getTextContent()
简单地以文本数据的形式访问 CDATA。 See example 没有类型检查,强制转换,e.getData()
。【参考方案2】:
由于所有先前的答案都使用基于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)
【讨论】:
【参考方案3】:CDATA
只是表示不应转义包含的数据。因此,只需获取标签文本。 XML 解析器应该返回没有CDATA
的清晰数据。
【讨论】:
获取文本数据:e.getTextContent();【参考方案4】:这里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 "";
【讨论】:
【参考方案5】:以下是示例 XML 文件和用于检索嵌入在主 xml 中的 CDATA 中的 XML 的代码。
<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;
【讨论】:
以上是关于如何为 <![CDATA[]]> 解析 XML的主要内容,如果未能解决你的问题,请参考以下文章
Boost XML 解析器可以支持 <![CDATA[ … ]]> 吗?