简体   繁体   English

在Java中使用Xpath定位具有特定namepace的元素

[英]Locating elements with specific namepace using Xpath in Java

I'm trying to list elements with specific namespace using Xpath in Java. 我正在尝试使用Java中的Xpath列出具有特定名称空间的元素。 I have the following xml file: 我有以下xml文件:

<pd:ProcessDefinition xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:pd="http://newsample/cred/process/2007"  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<pd:name>Processes/Schemas/GetInline.process</pd:name>
<pd:startName>StartThis</pd:startName>
<pd:startType>
    <xsd:element name="root">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="param" type="xsd:string"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</pd:startType>
<pd:endName>End</pd:endName>
<pd:endType>
    <xsd:element name="End" type="xsd:string"/>
</pd:endType>
<pd:activity name="MapAnyelement">
    <config>
        <element>
            <xsd:choice>
                <xsd:element name="param" type="xsd:string"/>
                <xsd:element ref="pfx:param1"/>
            </xsd:choice>
        </element>
    </config>
    <pd:coercions>
        <pd:coercion xpath="root" element="pfx:param1"/>
    </pd:coercions>
    <pd:inputBindings/>
</pd:activity>
<pd:activity name="MapComplex">
    <config>
        <element>
            <xsd:element name="mapComplex">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="complex1" type="xsd:string"/>
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
        </element>
    </config>
    <pd:inputBindings>
        <mapComplex>
            <complex1>
                <xsl:value-of select="1"/>
            </complex1>
        </mapComplex>
    </pd:inputBindings>
</pd:activity>
<pd:activity name="MapElement">
    <config>
        <element>
            <xsd:element name="mapElement" type="xsd:string"/>
        </element>
    </config>
    <pd:inputBindings>
        <mapElement>
            <xsl:value-of select="1"/>
        </mapElement>
    </pd:inputBindings>
</pd:activity>
</pd:ProcessDefinition>

I'm using the following code to find if any of the complex elements in the file have descendents which have namespace prefix xs ie they belong to namespace http://www.w3.org/2001/XMLSchema . 我正在使用以下代码查找文件中的任何复杂元素是否具有名称空间前缀为xs后代,即它们属于名称空间http://www.w3.org/2001/XMLSchema

String expression = "/ProcessDefinition/activity|//group/activity|/ProcessDefinition/starter";
NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(
            dDoc, XPathConstants.NODESET);
NodeListIterator iter = new NodeListIterator(nodeList);
while(iter.hasNext()) {
    Node nNode = iter.next();
    Element elem = (Element) nNode;
    String aName = elem.getAttribute("name");
    String ns = "http://www.w3.org/2001/XMLSchema";
    String schemaExpr = "//*[namespace-uri() = '"+ns+"']";
    NodeList nN = (NodeList) xPath.compile(schemaExpr).evaluate(nNode, XPathConstants.NODESET);
    System.out.println("##### NodeList: " + nN.getLength());
}

However the code always returns NodeList nN size as '0'. 但是,代码始终将NodeList nN大小返回为“ 0”。 What am I missing here? 我在这里想念什么?

In XPath, an unqualified name matches elements in no namespace. 在XPath中,无限定名称与没有名称空间的元素匹配。 So /ProcessDefinition won't match <pd:ProcessDefinition> in your source document. 因此, /ProcessDefinition与您的源文档中的<pd:ProcessDefinition>不匹配。

The simplest workaround is to use an XSLT 2.0+ processor (eg Saxon) and then either (1) set defaultXPathNamespace in the static context or (2) use steps of the form /*:ProcessDefinition/*:activity . 最简单的解决方法是使用XSLT 2.0+处理器(例如Saxon),然后(1)在静态上下文中设置defaultXPathNamespace或(2)使用形式为/*:ProcessDefinition/*:activity

If you want to stick with XPath 1.0 you can write expressions of the form /pd:ProcessDefinition/pd:activity and set a namespace context that recognises the prefix "pd"; 如果要坚持使用XPath 1.0,则可以编写/pd:ProcessDefinition/pd:activity形式的表达式,并设置一个可识别前缀“ pd”的名称空间上下文。 or you can write expressions in the form /*[local-name()='ProcessDefinition']/*[local-name()='activity']/... 或者您可以以/*[local-name()='ProcessDefinition']/*[local-name()='activity']/...的形式编写表达式

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

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