使用XPATH在Java中解析XML节点

时间:2011-11-09 06:04:37

标签: java xpath xml-parsing

我刚开始尝试使用Jaxp13XPathTemplate,但我对解析XML感到有点困惑。

以下是XML示例

<fxDataSets> 
<fxDataSet name="NAME_A">
  <link rel="self" href="http://localhost:8080/linkA"/>
  <baseCurrency>EUR</baseCurrency>
  <description>TEST DESCRIPTION A</description>
</fxDataSet>

<fxDataSet name="NAME_B">
  <link rel="self" href="http://localhost:8080/linkB"/>
  <baseCurrency>EUR</baseCurrency>
  <description>TEST DESCRIPTION B</description>
</fxDataSet>
<fxDataSets>  

我已经能够获得NAME_A和NAME_B但是我无法获得两个节点的描述。

以下是我的想法。

XPathOperations  xpathTemplate = new Jaxp13XPathTemplate();
    String fxRateURL = "http://localhost:8080/rate/datasets";
    RestTemplate restTemplate = new RestTemplate();
    Source fxRate = restTemplate.getForObject(fxRateURL,Source.class);
    List<Map<String, Object>> currencyList = xpathTemplate.evaluate("//fxDataSet", fxRate , new NodeMapper() {
        public Object mapNode(Node node, int i) throws DOMException 
        {
            Map<String, Object> singleFXMap = new HashMap<String, Object>();
            Element fxDataSet = (Element) node;
            String id    = fxDataSet.getAttribute("name");

            /* This part is not working
            if(fxDataSet.hasChildNodes())
            {
                NodeList nodeList = fxDataSet.getChildNodes();
                int length = nodeList.getLength();

                for(int index=0;i<length;i++)
                {
                    Node childNode = nodeList.item(index);
                    System.out.println("childNode name"+childNode.getLocalName()+":"+childNode.getNodeValue());
                }

            }*/

            return new Object();
        }
    });

3 个答案:

答案 0 :(得分:1)

尝试使用dom4j库,它是saxReader。

    InputStream is = FileUtils.class.getResourceAsStream("file.xml");

    SAXReader reader = new SAXReader();
    org.dom4j.Document doc = reader.read(is);
    is.close();
    Element content = doc.getRootElement();  //this will return the root element in your xml file
    List<Element> methodEls = content.elements("element"); // this will retun List of all Elements with name "element" 

答案 1 :(得分:1)

看看public <T> List<T> evaluate(String expression, Source context, NodeMapper<T> nodeMapper)

  • evaluateNodeMapper<T>作为其参数之一
  • 返回List<T>
  • 类型的对象

但是对于你给出的代码片段:

  • new NodeMapper()作为参数
  • 传递
  • 但是试图返回List<Map<String, Object>>,这肯定违反了api的合同。

可能的解决方案:

我假设您想要返回包含FxDataSet元素的<fxDataSet>...</fxDataSet>类型的对象。如果是这种情况,

  • 将参数传递为new NodeMapper<FxDataSet>()作为参数
  • 使用List<FxDataSet> currencyList = ...作为左手边的表达;
  • 将方法返回类型更改为public FxDataSet mapNode(Node node, int i) throws DOMException

另请参阅NodeMapper的文档。

当然,我没有使用Jaxp13XPathTemplate,但这应该是常见的Java概念,它帮助我找出实际上出了什么问题。我希望这个解决方案能够奏效。

答案 2 :(得分:0)

如果你想获得fxDataSet元素的子节点,你应该能够:

Node descriptionNode= fxDataSet.getElementsByTagName("description").item(0);