Xpath只选择元素

时间:2017-02-23 11:33:42

标签: java xpath

我正在使用javax.xml.xpath.XPath;尝试解析某些XML

有时某个元素可能会出现多次,当发生这种情况时,我想选择所有元素。

我有以下XML(标签名称和值已更改)

<Pearent>
 <a>hello</a>
 <a>world</a>
 <b>bye</b>
</Pearent>

我想获取所有节点的文本值

结果会直接插入Java HashMap,然后使用Thymeleaf

进行访问

如果我使用以下xpath /Pearent/a,我会"hello"

如果我使用/Pearent/a[1],我会"hello"

如果我使用/Pearent/a[2],我会得到“世界”

我还尝试仅定位Pearent节点,以便我使用/Pearent 我得"\n hello\n world\n bye\n" (请注意格式"\n "已自动插入)

我无法将pearent节点作为我问题的解决方案,因为有时候Pearent节点有其他我不想要的子节点。

有趣的是,我在在线解析器中尝试了相同的XMLXPath http://www.freeformatter.com/xpath-tester.html

我得到了不同的结果

如果我使用xpath /Pearent/a,我会<a>hello</a><a>world</a>

如果我使用xpath /Pearent/a[1],我会<a>hello</a>

如果我使用xpath /Pearent/a[2],我会<a>world</a>

如果我使用xpath /Pearent,我会<Pearent><a>hello</a><a>world</a><b>bye</b></Pearent>

我在这里看到两个不同之处:

  1. 在线解析器返回整个节点,我的解析器只返回节点的文本内容
  2. 在线解析器选择所有匹配的元素,我的解析器只选择匹配的第一个元素。
  3. 我的解析器功能如下:

    我的问题是:

    • 当我的xpath定位到具有多个子节点的节点时,如何控制似乎插入的格式?

    • 如何将所有子节点的文本值作为字符串(即Xpath /Pearent/a我希望获得"helloworld"

    • 如何将结果作为单独的节点返回,以便我可以在foreach中对它们使用Java循环(请记住我说结果已传递到hashmap } value)或ThymeLeaf

    MY XML PARSER CODE

    public String readValue(String XML , String Xpath) throws Exception{
    
            final DocumentBuilderFactory builderFactory =     DocumentBuilderFactory.newInstance();
            builderFactory.setNamespaceAware(Boolean.parseBoolean(propertyConfiguration.getNameSpaceAware()));
        final DocumentBuilder builder = builderFactory.newDocumentBuilder();
        Document xml = builder.parse(new InputSource(new StringReader(XML)));
    
        final XPath xPath = XPathFactory.newInstance().newXPath();
    
        String retrievedValue = xPath.compile(Xpath).evaluate(xml);
    
        return retrievedValue;
    }
    

    正在调用PARSER功能
    Map requiredData = new HashMap();
    requiredData.put("Title","/Pearent/a");
    

2 个答案:

答案 0 :(得分:0)

您可以修改下面的evaulate()方法。

您可以使用a获取标记名为xpath的所有节点,然后遍历节点以获取标记内的文本。

NodeList node = (NodeList) xPath.evaluate( "/Pearent/a", xml, XPathConstants.NODESET );

StringBuilder stringBuilder = new StringBuilder();

for ( int i = 0; i < node.getLength(); i++ ) {

    stringBuilder.append( node.item( i ).getTextContent() );    
}

System.out.println( stringBuilder.toString() );

<强>输出:

的HelloWorld

答案 1 :(得分:0)

要获得"helloworld",您可以使用

/Pearent/concat(./a[1]/text(), ./a[2]/text())

获取"hello world"

/Pearent/concat(./a[1]/text(), " ", ./a[2]/text())