Xpath在移至其他元素时添加“自定义字符串”

时间:2019-04-13 16:38:01

标签: java xml xpath

我有一个问题要使用XPATH和JAVA查找XML元素,但其中有一些约束。 让我知道是否需要更多信息,或者是否需要此问题,请提供链接以帮助您阅读更多信息。

任何需要更改内容的指针都会有所帮助

下面是我当前拥有的XML。

从下面的XML中,我只想获取<Name>的{​​{1}},<LocalAddress><Zipcode>的文本,然后创建一个<Name = 123 School>的HashMap。是键,值是<Name>

的联接

到目前为止,我已经能够获取Name,LocalAddress和zipcode的所有列表,但不能获取特定<LocalAddress and ZipCode>元素的列表。

<Name>

请检查下面我尝试过的代码

<SchoolRoot>
<School>
    <Name>123 School</Name>
    <Address>
        <LocalAddress>
            <Street>This a fixed value ( In this example, lets say ) 123 St </Street>
            <AptNo>This is user input Value ( Can be anything )</AptNo>
        </LocalAddress>
        <LocalAddress>
            <Street>This a fixed value ( In this example, lets say ) 345 St </Street>
            <AptNo>This is user input Value ( Can be anything )</AptNo>
        </LocalAddress>
        <ZipCode>123</ZipCode>
    </Address>
</School>
<School>
    <Name>34564 School</Name>
    <Address>
        <LocalAddress>
            <Street>This a fixed value ( In this example, lets say ) 678 St </Street>
            <AptNo>This is user input Value ( Can be anything )</AptNo>
        </LocalAddress>
        <LocalAddress>
            <Street>This a fixed value ( In this example, lets say ) 91011 St </Street>
            <AptNo>This is user input Value ( Can be anything )</AptNo>
        </LocalAddress>
        <ZipCode>121314</ZipCode>
    </Address>
</School>
</SchoolRoot>

输出结果如下:

package com.gami.leetcode;

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 org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import java.io.StringReader;

public class xPathExample
{
    public static void main(String[] args) throws Exception
    {
        //Build DOM


        String xml = "<SchoolRoot>\n" +
                "<School>\n" +
                "    <Name>123 School</Name>\n" +
                "    <Address>\n" +
                "        <LocalAddress>\n" +
                "            <Street>This a fixed value ( In this example, lets say ) 123 St </Street>\n" +
                "            <AptNo>This is user input Value ( Can be anything )</AptNo>\n" +
                "        </LocalAddress>\n" +
                "        <LocalAddress>\n" +
                "            <Street>This a fixed value ( In this example, lets say ) 345 St </Street>\n" +
                "            <AptNo>This is user input Value ( Can be anything )</AptNo>\n" +
                "        </LocalAddress>\n" +
                "        <ZipCode>123</ZipCode>\n" +
                "    </Address>\n" +
                "</School>\n" +
                "<School>\n" +
                "    <Name>456 School</Name>\n" +
                "    <Address>\n" +
                "        <LocalAddress>\n" +
                "            <Street>This a fixed value ( In this example, lets say ) 678 St </Street>\n" +
                "            <AptNo>This is user input Value ( Can be anything )</AptNo>\n" +
                "        </LocalAddress>\n" +
                "        <LocalAddress>\n" +
                "            <Street>This a fixed value ( In this example, lets say ) 91011 St </Street>\n" +
                "            <AptNo>This is user input Value ( Can be anything )</AptNo>\n" +
                "        </LocalAddress>\n" +
                "        <ZipCode>121314</ZipCode>\n" +
                "    </Address>\n" +
                "</School>\n" +
                "</SchoolRoot>";

        InputSource source = new InputSource(new StringReader(xml));

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true); // never forget this!
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(source);

        XPathFactory xpathFactory = XPathFactory.newInstance();
        XPath xpath = xpathFactory.newXPath();

        XPathExpression expr = xpath.compile("//School/Name|//Address/LocalAddress/*");
        Object result = expr.evaluate(doc, XPathConstants.NODESET);
        NodeList nodes = (NodeList) result;

        for (int i = 0; i < nodes.getLength(); i++) {
            System.out.println(nodes.item(i).getFirstChild().getNodeValue());
           }
        }
}

,但预期输出一次包含一个学校详细信息,包括邮政编码。 像这样

123 School
This a fixed value ( In this example, lets say ) 123 St 
This is user input Value ( Can be anything )
This a fixed value ( In this example, lets say ) 345 St 
This is user input Value ( Can be anything )
456 School
This a fixed value ( In this example, lets say ) 678 St 
This is user input Value ( Can be anything )
This a fixed value ( In this example, lets say ) 91011 St 
This is user input Value ( Can be anything )

1 个答案:

答案 0 :(得分:0)

您可以通过指定相等条件[Name='123 School']来限制结果节点,如下所示:

XPathExpression expr = xpath.compile("//School[Name='123 School']/Name|//School[Name='123 School']/Address/LocalAddress/*");

这将产生您预期的结果(使用this online IDE测试):

123 School This a fixed value ( In this example, lets say ) 123 St This is user input Value ( Can be anything ) This a fixed value ( In this example, lets say ) 345 St This is user input Value ( Can be anything )

回复评论:未找到将自定义节点添加到返回的节点列表的xpath方法。但是,由于您知道nodelist输出的结构是什么-您可以在输出循环中使用以下命令:

for (int i = 0; i < nodes.getLength(); i++) {
   if(i%5==0)
      System.out.println("Custom Message - your text");
   System.out.println(nodes.item(i).getFirstChild().getNodeValue());
   }
}

推荐: