在 Java 中使用 EvaluateXpath 返回缺失标签的空值

Returning Null values for missing tags with EvaluateXpath in Java

我正在通过评估路径检索 XML 标签值,假设我有 3 个带有图书信息的标签: 书籍信息包括:姓名 - 年份 - 作者和 1 个标签作者姓名已丢失且未出现在我的标签中,我想要一个显示 1 个作者姓名 + 空值的数组,这表明 2 个标签没有已指定,如下所示: 如您所见,第二个标签不包含作者姓名,第三个标签没有任何作者姓名标签,如下所示: 我非常感谢任何指导/提示/帮助。 :-)

Author: [John Smith,null,null]

我的 XML 文件:

<?xml version="1.0" encoding="UTF-8"?>
<perldata>
    <item key="book">
        <item key="name">My Book Name</item>
        <item key="year">2019</item>
        <item key="author">John Smith</item>
    </item>
    <item>
        <item key="name">Anonymous Book Name 1</item>
        <item key="year">2018</item>
        <item key="author"></item>
    </item>
    <item>
        <item key="name">Her Book Name</item>
        <item key="year">2018</item>
    </item>
</perldata>

这表明第三个标签不包含作者姓名标签。 我不知道如何在 EvaluateXpath 中显示空值:(真的需要帮助)

         String fileName="book.xml";
         Document document = getDocument(fileName);

                     // Defining Variables
                     //   String xpathExpression = "";
                       FileWriter fw = null; 
                       BufferedWriter bw = null; 
                       PrintWriter pw = null;

                    //Using Document Builder
         DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
                            documentBuilderFactory.setNamespaceAware(true);
                            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
                            Document doc1 = documentBuilder.parse(fileName);


                         /*******Get attribute values using xpath******/
                        XPathFactory xpathFactory = XPathFactory.newInstance();
                        XPath xpath = xpathFactory.newXPath();
                try{
                        fw = new FileWriter("/root/Desktop/book.txt");
                        bw = new BufferedWriter(fw);
                        pw = new PrintWriter(bw)
                        pw.println("BookName: "+evaluateXpath(document, "/perldata/item[@key=book]/item[@key='name']/text()"));
                        pw.println("year: "+evaluateXpath(document, "/perldata/item[@key=book]/item[@key='year']/text()"))
                        pw.println("Author: "+evaluateXpath(document, "/perldata/item[@key=book]/item[@key='author']/text()"))
                pw.flush(); }
catch (IOException e) 
        { e.printStackTrace(); } } }

        private static List<String> evaluateXPath(Document document, String xpathExpression) throws Exception 
        {
            // Create XPathFactory object
            XPathFactory xpathFactory = XPathFactory.newInstance();

            // Create XPath object
            XPath xpath = xpathFactory.newXPath();

            List<String> values = new ArrayList<>();
            try
            {
                // Create XPathExpression object
                XPathExpression expr = xpath.compile(xpathExpression);

                // Evaluate expression result on XML document
                NodeList nodes = (NodeList) expr.evaluate(document, XPathConstants.NODESET);

                for (int i = 0; i < nodes.getLength(); i++) {
                    values.add(nodes.item(i).getNodeValue());
                }

            } catch (XPathExpressionException e) {
                e.printStackTrace();
            }

            return values;
        }


        private static Document getDocument(String fileName) throws Exception 
        {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setNamespaceAware(true);
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder.parse(fileName);
            return doc;
        }

        }

总结:

Trim标签的文本内容,判断结果字符串是否为空

详情:

问题中的XML只有一个标签包含key="book"。我假设所有 3 个部分都应该有这个,所以我们知道每个部分代表一本书。

因此,我假设您有一个如下所示的 XML 文件,其中包括一个空的“作者”标签和一个完全缺失的“作者”标签:

<?xml version="1.0" encoding="UTF-8"?>
<perldata>
    <item key="book">
        <item key="name">My Book Name</item>
        <item key="year">2019</item>
        <item key="author">John Smith</item>
    </item>
    <item key="book">
        <item key="name">Anonymous Book Name 1</item>
        <item key="year">2018</item>
        <item key="author"></item>
    </item>
    <item key="book">
        <item key="name">Her Book Name</item>
        <item key="year">2018</item>
    </item>
    <item key="book">
        <item key="name">Another Book Name</item>
        <item key="year">2019</item>
        <item key="author">Jane Jones</item>
    </item>
</perldata>

假设如上,可以打印出所有名字(包括null个名字)如下:

File file = new File("C:/tmp/Book2.xml");
FileInputStream fis = new FileInputStream(file);
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(fis);
XPath xPath = XPathFactory.newInstance().newXPath();
NodeList bookNodes = (NodeList) xPath.compile("//item[@key='book']")
        .evaluate(xmlDocument, XPathConstants.NODESET);

List<String> authors = new ArrayList();

for (int i = 0; i < bookNodes.getLength(); i++) {
    Node bookNode = bookNodes.item(i);
    Node authorNode = (Node) xPath.compile("./item[@key='author']")
            .evaluate(bookNode, XPathConstants.NODE);

    if (authorNode == null) {
        authors.add(null);
    } else {
        String s = authorNode.getTextContent().trim();
        authors.add(s.isEmpty() ? null : s);
    }
}
System.out.println(authors);

最后的打印语句是这样的:

[John Smith, null, null, Jane Jones]

补充说明:

这将循环遍历文件中的所有 <item key="book"> 部分。对于每个部分,它然后执行此目标搜索,但 仅在该部分:

Node authorNode = (Node) xPath.compile("./item[@key='author']")
        .evaluate(bookNode, XPathConstants.NODE);

evaluate使用当前bookNode作为起点。

之后,我们可以检查所有可能的结果:

  • 我们找到了一个 key="author" 标签 - 它包含作者姓名。
  • 我们找到了一个 key="author" 标签 - 但其中没有名称。
  • book 节点没有 key="author" 标签。