繁体   English   中英

XPath 表达式不会得到节点列表

[英]XPath expression will not get node list

我有一些来自 SOAP 响应的 XML,我想从中获取所有 CRM_Company 节点,但不知何故我不会得到任何结果。 我尝试过不同的表达方式,但我猜

//ns:CRM_公司

应该工作,但它不以某种方式。

XML 看起来像这样

<Soap:Envelope xmlns:Soap="http://schemas.xmlsoap.org/soap/envelope/">
   <Soap:Body>
      <ReadMultiple_Result xmlns="urn:microsoft-dynamics-schemas/page/crm_company">
         <ReadMultiple_Result>
            <CRM_Company>               
               <No>12345</No>
               <Name>Name</Name>            
            </CRM_Company>
         </ReadMultiple_Result>
      </ReadMultiple_Result>
   </Soap:Body>
</Soap:Envelope>

我的 Java 代码看起来像这样

    public static void main(String[] args) {
        try {
            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
            builderFactory.setNamespaceAware(true);
            DocumentBuilder builder = builderFactory.newDocumentBuilder();
            Document xmlDocument = builder.parse(new ByteArrayInputStream(XML.getBytes(StandardCharsets.UTF_8)));
            XPath xPath = XPathFactory.newInstance().newXPath();
            xPath.setNamespaceContext(new NamespaceResolver(xmlDocument));
            Vector<String> ret = new Vector<>();

            NodeList nodeList = (NodeList) xPath.compile("//ns:CRM_Company").evaluate(xmlDocument, XPathConstants.NODESET);
            for (int i = 0; i < nodeList.getLength(); i++) {
                Node node = nodeList.item(i);
                ret.add(node.getNodeValue());
            }
            System.out.println(ret);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

这是我的“NamespaceResolver”类

public class NamespaceResolver implements NamespaceContext
{
    // Store the source document to search the namespaces
    private final Document  sourceDocument;


    public NamespaceResolver(Document document)
    {
        sourceDocument = document;
    }

    // The lookup for the namespace uris is delegated to the stored document.
    public String getNamespaceURI(String prefix)
    {
        if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) {
            return sourceDocument.lookupNamespaceURI(null);
        } else if(prefix.equals("ns")) {
            return "urn:microsoft-dynamics-schemas/page/crm_company";
        } else {
            return sourceDocument.lookupNamespaceURI(prefix);
        }
    }

    public String getPrefix(String namespaceURI)
    {
        return sourceDocument.lookupPrefix(namespaceURI);
    }

    @SuppressWarnings("rawtypes")
    public Iterator getPrefixes(String namespaceURI)
    {
        return null;
    }
}

我不知道为什么您的命名空间解析器不起作用,但我可以建议一种替代方法,即使用不需要使用限定名称引用元素的 XPath 表达式。 例如

//*[local-name()='CRM_Company'][namespace-uri()='urn:microsoft-dynamics-schemas/page/crm_company']

现在我正在使用Saxon并让它运行

        Processor processor = new Processor(false);
        try {
            Path path = Files.createTempFile(null, ".xml");
            try(BufferedWriter bw = new BufferedWriter(new FileWriter(path.toString()))) {
                bw.write(XML);
            }
            path.toFile().deleteOnExit();
            XdmNode document = processor.newDocumentBuilder().build(path.toFile());
            XPathCompiler xPathCompiler = processor.newXPathCompiler();
            XdmValue evaluate = xPathCompiler.evaluate("//*:CRM_Company", document);
            System.out.println(evaluate.toString());
        } catch (IOException | SaxonApiException e) {
            e.printStackTrace();
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM