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

标签 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 格式会阻止解析器继续。

最佳答案

问题:您的文件根本就不是“格式良好的 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/

    相关文章:

    java - Selenium XPath - 如何查找紧邻前面的元素

    java - 如何使用ssl证书创建okhttp

    mysql - 在 MySQL 中解析 XML 字符串

    html - XML/XSLT - XML 解析错误 : no element found

    java - XML 文件位于内存中,而不是作为磁盘上的文件

    xpath - 简单解释xpath和xquery

    sql - SQL for XML Path使用节点名称和嵌套的数据值

    java数据表服务器端问题

    Java 按钮悬停

    java - 如何在 if、嵌套 if、else 语句中使用具有两种含义的 boolean 值