简体   繁体   中英

How to check if node has one or more specific attributes with XPath in Java?

I would like to get every child node which contains one of the these attributes: type, ref, base. The value of each attribute doesn't matter, I just want to check if the attribute exists.

This is how I do it now:

private void addRequiredNodeAndChildren(Node n) {    
            XPath xpath = XPathFactory.newInstance().newXPath();
            String expression = "*//*[@base or @ref or @type]";
            XPathExpression expr = xpath.compile(expression);
            NodeList referList = (NodeList) expr.evaluate(n, XPathConstants.NODESET);
            ..
}

This expression works fine but in one case I don't get all expected nodes:

 <xs:complexType name="ListElement">
        <xs:annotation>
            <xs:documentation>
            </xs:documentation>
        </xs:annotation>
        <xs:attribute name="transferMode" type="myprefix:dataTransferMode"
            use="optional">
            <xs:annotation>
                <xs:documentation>Documentation for attribute
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>

I expect to get the node with the expression above, but unfortunately I don't get it. Change the expression to

//*[@base or @ref or @type] 

didn't help either, as a result of that I got every node from the XML with one of the attributes but I want to get only the child nodes of the given node n. I also tried

*//*[@base] or *//*[@ref] or *//*[@type]

as expression but that didn't work as well.

Has anyone ideas how to solve my problem?

//*[@base or @ref or @type] didn't help either, as a result of that I got every node from the XML with one of the attributes but I want to get only the child nodes of the given node n

That's because '//' searches the whole document. Your predicate is correct, but the sequence you are filtering is wrong. To get the children of the context node, use

*[@base or @ref or @type]

Incidentally, if you're trying to list all the attributes in XSD that contain QNames referring to other declarations in the schema, your list is incomplete.

看来您想要的是:

*[descendant-or-self::*[@base or @ref or @type] ]

Thank you all for your help!

I found a solution which is not very pretty but at least it works:

*[@base or @ref or @type] | *//*[@base or @ref or @type]

EDIT: I adapted Dimitre Novatchev's solution, which solves the problem too:

descendant-or-self::*[@base or @ref or @type]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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