如何在java中处理嵌套的xml文件?

时间:2017-04-25 22:46:09

标签: java xml xpath

我正在与纽约时报语料库合作开展一个项目,现在我无法使用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格式会阻止解析器继续。

1 个答案:

答案 0 :(得分:2)

问题:您的文件不是“格式良好的XML”。

它们似乎是不同XML节的BUNCH,所有这些节都集中在一个文件中。

所以是的,你必须“将这个巨大的XML文件分成多个XML文件”。

SUGGESTIONS: 1.“分隔符”告诉您一个XML节结束和下一个XML节开始的位置似乎是<?xml version="1.0" encoding="UTF-8"?>。使用它!

  1. 编写一个解析“大文件”的脚本,复制每一行,直到它到达“”标题。它关闭当前的“小文件”,打开下一个文件,然后继续复制,一次一个节。

  2. 您可以通过将节复制成Java字符串节来完成同样的事情,而不是复制文件。

  3. '希望有所帮助。