【问题标题】:XPath to select list of nodes in JavaXPath 选择 Java 中的节点列表
【发布时间】:2015-07-18 15:53:07
【问题描述】:

我有以下 XML 文件:

<RecordSet>
  <Record>
    <ID>001</ID>
    <TermList>
      <Term>Term1</Term>
      <Term>Term2</Term>
      <Term>Term3</Term>
    </TermList>
  </Record>
  <Record>
    <ID>002</ID>
    <TermList>
      <Term>Term3</Term>
      <Term>Term4</Term>
      <Term>Term5</Term>
    </TermList>
  </Record>
</RecordSet>

并需要将其解析为“ID-Ter​​m”文件,即,

001 Term1
001 Term2
001 Term3
002 Term3
002 Term4
002 Term5

目前我有以下应用:

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.xml.parsers.*;
import javax.xml.xpath.*;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class MedlineParser {

    public static void main(String[] args) {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        DocumentBuilder builder;
        Document doc = null;
        try {
            builder = factory.newDocumentBuilder();
            doc = builder.parse("/home/andrej/Documents/test.xml");
            // Create XPathFactory object
            XPathFactory xpathFactory = XPathFactory.newInstance();
            // Create XPath object
            XPath xpath = xpathFactory.newXPath();
            try {
                XPathExpression expr1 = xpath.compile("/RecordSet/Record/ID/text()");
                NodeList nodes1 = (NodeList) expr1.evaluate(doc, XPathConstants.NODESET);
                for (int i = 0; i < nodes1.getLength(); i++) {
                    String id = nodes1.item(i).getNodeValue();
                    XPathExpression expr2 = xpath.compile("/RecordSet/Record/TermList/Term/text()");
                    NodeList nodes2 = (NodeList) expr2.evaluate(doc, XPathConstants.NODESET);
                    for (int j = 0; j < nodes2.getLength(); j++) {
                        System.out.println(id + " " + nodes2.item(i).getNodeValue());
                    }
                }
            } catch (XPathExpressionException e) {
                e.printStackTrace();
            }

        } catch (IOException | ParserConfigurationException | SAXException e) {
            e.printStackTrace();
        }
    }
}

很遗憾,目前程序输出是:

001 Term1
001 Term1
001 Term1
001 Term1
001 Term1
001 Term1
002 Term2
002 Term2
002 Term2
002 Term2
002 Term2
002 Term2

知道 XPath 表达式有什么问题吗?

【问题讨论】:

    标签: java xml xpath


    【解决方案1】:

    两个问题:

    1. XPath 必须考虑在第一个循环中迭代的ID 节点的索引。您当前的 XPath 每次为每个 ID 节点获取所有 Term 节点。您应该将其更改为:

      XPathExpression expr2 = xpath.compile("/RecordSet/Record[" + (i + 1) + "]/TermList/Term/text()");
      
    2. 您在内部 for 循环中有错字。你应该使用j 而不是i

      for (int j = 0; j < nodes2.getLength(); j++) {
          System.out.println(id + " " + nodes2.item(j).getNodeValue());
      }
      

    【讨论】:

    • 有效,但根据 XML 文件的大小,这可能效果不佳。
    【解决方案2】:

    似乎您正在打印所有 id 和术语的笛卡尔积。

    这样会更容易:

    1. 使用 XPath 表达式 /RecordSet/Record 选择并循环遍历所有记录节点。
    2. 对于每个记录节点,使用记录节点作为上下文节点,选择 id(使用 XPath ID)和术语(使用 XPath Termlist/Term)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-08
      • 2012-07-15
      • 1970-01-01
      • 2011-06-29
      • 2013-11-28
      • 1970-01-01
      相关资源
      最近更新 更多