【发布时间】:2014-10-06 04:02:53
【问题描述】:
在搜索现有的 CDATA 讨论后,我发现没有一个能够实现我正在尝试的目标。
是否可以在标签不唯一的 CDATA 中进行解析?
下面是 XML 文档,我试图在下面的第 5 行检索具有多个感兴趣字段(即数据加载、质量、状态、索引)的 CDATA 块中的每个字段。每个字段在 CDATA 块中都用“li”标签标记(即使它是字符数据空间):
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.0">
<Document>
<name>area Area Date: 2014-07-31</name>
<Placemark><name>P07L327</name><Point><coordinates>-96.26879,85.19125</coordinates></Point><description><![CDATA[<ol><li> Data Loaded: NO</li><li>Quality: 5</li><li>Status: UP</li><li>Index: 72</li></eol>]]></description><Style> id = "colorIcon"</Style></Placemark>
<coordinates>-96.26879,85.19125,0 -96.26879,85.19125,0 -96.26879,85.19125,0 -96.26879,85.19125,0 -96.26879,45.14698,0 </coordinates>
</Document>
</kml>
目前输出是这样的:
Name: <ol><li> Data Loaded: NO</li><li>Quality: 5</li><li>Status: UP</li><li>Index: 72</li></eol>
在 CDATA 块中,我的意图是为每个字段输出一个新行以及相应的结果。
下面是到目前为止编写的代码,它给出了上面列出的当前输出:
package com.lucy.seo;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.CharacterData;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import java.io.File;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Comment;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;
public class ReadXMLFile {
public static void main(String[] args ) throws Exception {
File fXmlFile = new File("C:/XML_UltraEdit/XML_Sandbox/Oracle_Java_Project/Test_Doc.xml");
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(fXmlFile);
doc.getDocumentElement().normalize();
System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
NodeList nList = doc.getElementsByTagName("Placemark");
System.out.println("----------------------------");
for (int temp = 0; temp < nList.getLength(); temp++) {
Element element = (Element) nList.item(temp);
NodeList name = element.getElementsByTagName("description");
Element line = (Element) name.item(0);
System.out.println("Name: " + getCharacterDataFromElement(line));
}
}
public static String getCharacterDataFromElement(Element f) {
NodeList list = f.getChildNodes();
String data;
for(int index = 0; index < list.getLength(); index++){
if(list.item(index) instanceof CharacterData){
CharacterData child = (CharacterData) list.item(index);
data = child.getData();
if(data != null && data.trim().length() > 0)
return child.getData();
}
}
return "";
}
}
感谢您对此的任何帮助! -- 谢谢!
2014 年 9 月 2 日更新
使用最终解决方案更新编辑。感谢所有在这里发布解决方案并提供帮助的人。由于库冲突,解决方案分为两段代码/文件:
//First file which is input to the second file followed afterwards
import java.io.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.CharacterData;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class ReadXMLFile {
public static void main(String[] args ) throws Exception {
PrintStream out = new PrintStream(new FileOutputStream("C:/XML_UltraEdit/XML_Sandbox/NetBeans_Java_Project/temp_file.html"));
System.setOut(out);
File fXmlFile = new File("C:/XML_UltraEdit/XML_Sandbox/NetBeans_Java_Project/raw_input.xml");
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(fXmlFile);
//optional, but recommended
//read this - http://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-java-how-does-it-work
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("Placemark");
//create a buffered reader that connects to the console, we use it so we can read lines
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.println("<html xlmns=http://www.w3.org/1999/xhtml>");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
Element eElement = (Element) nNode;
Element element = (Element) nList.item(temp);
NodeList name = element.getElementsByTagName("description");
Element line = (Element) name.item(0);
System.out.println("<bracket><li>Name: " + eElement.getElementsByTagName("name").item(0).getTextContent() + "</li>");
System.out.println("<description>Description: " + getCharacterDataFromElement(line) + "</description></bracket>");
}
System.out.println("</html>");
//read a line from the console
String lineFromInput = in.readLine();
//output to the file a line
out.println(lineFromInput);
out.close();
}
public static String getCharacterDataFromElement(Element f) {
NodeList list = f.getChildNodes();
String data;
for(int index = 0; index < list.getLength(); index++){
if(list.item(index) instanceof CharacterData){
CharacterData child = (CharacterData) list.item(index);
data = child.getData();
if(data != null && data.trim().length() > 0)
return child.getData();
}
}
return "";
}
}
//Second File
package ReadXMLFile_part2;
import java.io.*;
import org.jsoup.Jsoup;
import org.jsoup.select.Elements;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ReadXMLFile_part2 {
public static void main(String[] args) throws Exception {
PrintStream out = new PrintStream(new FileOutputStream("C:/XML_UltraEdit/XML_Sandbox/NetBeans_Java_Project/PA-PTH013_Output_Meters.xml"));
System.setOut(out);
System.out.println("*** JSOUP ***");
File input = new File("C:/XML_UltraEdit/XML_Sandbox/NetBeans_Java_Project/temp_file.html");
Document doc = null;
try {
doc = Jsoup.parse(input,"UTF-8", "http://www.w3.org/1999/xhtml" );
} catch (IOException ex) {
Logger.getLogger(ReadXMLFile_part2.class.getName()).log(Level.SEVERE, null, ex);
}
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
Elements brackets = doc.getElementsByTag("bracket");
for (Element bracket : brackets) {
Elements lis = bracket.select("li");
for (Element li : lis){
System.out.println(li.text());
}
break;
}
System.out.println();
//read a line from the console
String lineFromInput = in.readLine();
//output to the file a line
out.println(lineFromInput);
out.close();
}
}
【问题讨论】:
-
您可以为整个 CDATA 块编写一个处理程序,然后对其进行自己的解析,但
CDATA的全部意义在于它被定义为不应被解析的纯字符数据XML 阅读器 =) -
谢谢,但是我如何解析具有相同 XML 标记的文本作为 li 元素?我找到的最接近的是:[link] stackoverflow.com/questions/12889253/…
-
您已经知道如何将该 CDATA 作为原始数据获取,因此诀窍是使用 second 解析器(然后是 HTML 解析器,而不是 XML 解析器)并运行您的通过那个 CDATA 字符串。
-
谢谢,正如您所说,我最终使用了第二个解析器(使用 HTML)并且已经工作但遇到了另一个问题。我已经在另一个线程上发布了完整的问题:[link] (stackoverflow.com/questions/25491424/…)
标签: java xml parsing dom cdata