【问题标题】:How to parse a complex XML using Xpath如何使用 Xpath 解析复杂的 XML
【发布时间】:2017-08-06 19:07:31
【问题描述】:

我有一个如下的 XML:

<Service xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns="someurl" xsi:schemaLocation="someurl Sample.xsd">
    <RequestControl>
        <requestID>100129</requestID>
        <Control>
            <requesterName>Admin</requesterName>
            <requesterLanguage>100</requesterLanguage>
        </Control>
    </RequestControl>
    <Inquiry>
        <InquiryType>getParty</InquiryType>
        <InquiryParam>
            <Param name="PartyId">854850029276139020</Param>
        </InquiryParam>
    </Inquiry>
</Service>

我想使用 XPath XML Parser 从标记中提取值“getParty”。我使用以下作为我的表达方式:

expression = xPath.compile("/Service/Inquiry/InquiryType/text()");

如何才能写出准确完整的java代码呢?我只想提取&lt;InquiryType&gt;getParty&lt;/InquiryType&gt; 的值。

【问题讨论】:

  • 我在下面使用:NodeList xpathNodeList = (NodeList) expression.evaluate(doc, XPathConstants.NODESET); System.out.println("xpathNodeList 长度为:" +xpathNodeList.getLength());但是它打印长度为 0。
  • 尝试使用XPathConstants.STRING
  • 它说:线程“main”中的异常 java.lang.ClassCastException: java.lang.String 与 org.w3c.dom.NodeList 不兼容
  • @Som,使用你的代码我得到 xpathNodeList.getLength() = 1
  • @jeanr :请您帮我解决这个问题。在我的情况下,它显示 0 作为长度。我再次检查了一遍。

标签: java xml xpath saxparser


【解决方案1】:

尝试您的代码,它看起来对我来说工作正常。这就是我所做的

public static void main(String ... args) throws ParserConfigurationException, IOException, SAXException, XPathExpressionException {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document doc = builder.parse(System.getProperty("user.dir") + "/src/main/resources/test.xml");
    XPathFactory xPathfactory = XPathFactory.newInstance();
    XPath xpath = xPathfactory.newXPath();
    XPathExpression expression = xpath.compile("/Service/Inquiry/InquiryType/text()");
    NodeList xpathNodeList = (NodeList) expression.evaluate(doc, XPathConstants.NODESET);
    System.out.println("InquiryType is : " +xpathNodeList.item(0));
}

使用 test.xml 包含您正在使用的 xml

<Service xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns="someurl" xsi:schemaLocation="someurl Sample.xsd">
<RequestControl>
    <requestID>100129</requestID>
    <Control>
        <requesterName>Admin</requesterName>
        <requesterLanguage>100</requesterLanguage>
    </Control>
</RequestControl>
<Inquiry>
    <InquiryType>getParty</InquiryType>
    <InquiryParam>
        <Param name="PartyId">854850029276139020</Param>
    </InquiryParam>
</Inquiry>
</Service>

【讨论】:

  • @DanielHaley,默认情况下,文档构建器不支持命名空间,因此如果 XML 中只有默认命名空间且未使用前缀,则您可能会摆脱使用的路径。但是,我认为像 Saxon 之类的其他实现需要一个命名空间感知 DOM。
  • 我发现我做错了。我正在使用以下行:dbFactory.setNamespaceAware(true);当我注释掉代码时,它就可以正常工作了。
【解决方案2】:

我正在使用以下方法:

public static String inputXmlXPathParser(String inputXml){


        //==================================================X-Path Parser =============================================================//

        String transactionName = StringUtils.EMPTY;

        try {

            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            dbFactory.setNamespaceAware(true);
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(new InputSource( new StringReader(inputXml)));
            doc.getDocumentElement().normalize();

            System.out.println("Root element :" + doc.getDocumentElement().getNodeName());

            XPathFactory xPathfactory = XPathFactory.newInstance();
            XPath xpath = xPathfactory.newXPath();
            XPathExpression expression = xpath.compile("/Service/Inquiry/InquiryType/text()");
            NodeList xpathNodeList = (NodeList) expression.evaluate(doc, XPathConstants.NODESET);
            System.out.println("InquiryType is : " +xpathNodeList.item(0));

        } catch (ParserConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (XPathExpressionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }    


        return transactionName;

    }

【讨论】:

  • @jeanr :我可以正确打印根元素,但不能正确打印 "xpathNodeList.item(0))" 。它打印空。
  • 删除命名空间内容后,我的代码运行良好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-17
  • 2013-02-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多