我正在与纽约时报语料库合作开展一个项目,但现在我在使用 xml 文件检索大部分项目的文本内容时遇到了困难。
语料库中每年都包含数百兆字节的 xml 文件,其中该年的每篇文章都有一个 xml 文件。
我想从 body.content 标记中检索文本。
特定年份的 xml 文件的一般格式如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE nitf SYSTEM "http://www.nitf.org/IPTC/NITF/3.3/specification/dtd/nitf-3-3.dtd">
<nitf change.date="June 10, 2005" change.time="19:30" version="-//IPTC//DTD NITF 3.3//EN">
<head>
<title> Article1 </title>
</head>
<body>
<body.content>
</body.content>
</body>
...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE nitf SYSTEM "http://www.nitf.org/IPTC/NITF/3.3/specification/dtd/nitf-3-3.dtd">
<nitf change.date="June 10, 2005" change.time="19:30" version="-//IPTC//DTD NITF 3.3//EN">
<head>
<title> Article2 </title>
</head>
<body>
<body.content>
</body.content>
</body>
...
这是我在尝试解析 XML 文件时使用的类和方法:
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import java.io.FileWriter;
import java.util.ArrayList;
public class XMLParser {
public static XMLParser parser = new XMLParser();
public static final String TEXT_LOCATION = "/txts/";
private XMLParser(){
}
public static XMLParser getParser(){
return parser;
}
public void XMLtoText(String xmlLocation, int year) throws Exception{
ArrayList<String> text = new ArrayList<String>();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(xmlLocation);
XPathFactory xFactory = XPathFactory.newInstance();
XPath xpath = xFactory.newXPath();
XPathExpression expr = xpath.compile("//body.content/text()");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
for (int i=0; i<nodes.getLength();i++){
text.add(nodes.item(i).getNodeValue().toString());
}
try {
FileWriter writer = new FileWriter(TEXT_LOCATION + year + ".txt");
for(String str : text){
writer.write(str);
}
writer.close();
} catch(Exception e){
}
}
}
这是我在尝试解析时遇到的错误。
[Fatal Error] nitf-3-3.dtd:1:3: The markup declarations contained or pointed to by the document type declaration must be well-formed.
org.xml.sax.SAXParseException; systemId: http://www.nitf.org/IPTC/NITF/3.3/specification/dtd/nitf-3-3.dtd; lineNumber: 1; columnNumber: 3; The markup declarations contained or pointed to by the document type declaration must be well-formed.
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:257)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:339)
at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:177)
at ____.XMLParser.XMLtoText(XMLParser.java:45)
at ____.Main.main(Main.java:23)
我想知道是否有办法将这个巨大的 XML 文件拆分为每篇文章的多个 XML 文件。这将使解析每篇文章中的文本变得更加容易,而不会出现无效 xml 文件的问题。我尝试从除顶部元素之外的每个元素中删除 xml 声明和 DOCTYPE nitf,但这似乎没有解决问题。从顶层删除 DOCTYPE(第二行)似乎可以解析到第二个 XML 声明,其中无效的 XML 格式会阻止解析器继续。
最佳答案
问题:您的文件根本就不是“格式良好的 XML”。
它们似乎是一堆不同的 XML 节,全部聚集在一个文件中。
所以,是的,您必须“将这个巨大的 XML 文件拆分为多个 XML 文件”。
建议:
1. 告诉您一个 XML 节结束位置和下一个 XML 节开始位置的“分隔符”似乎是 <?xml version="1.0" encoding="UTF-8"?>
。使用它!
编写一个解析“大文件”的脚本,复制每一行,直到它到达“”标题。它关闭当前的“小文件”,打开下一个文件,然后继续复制,一次一节。
您可以通过将节逐节复制到 Java 字符串中来完成相同的操作,而不是复制文件。
“希望有帮助。
关于java - 如何在java中处理嵌套的xml文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43622200/