使用 XPath 来 select XSD 文件中的一个元素总是 returns 一个空列表

Using XPath to select an element in XSD file always returns an empty list

我有一个 XSD 文件如下。我想select节点xs:element基于它的属性值name=content。我使用下面的代码来获取该元素,但它总是 returns 一个空列表。

String strBuiltinSchema = new String(schemaContent, StandardCharsets.UTF_8);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(strBuiltinSchema)));

XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xPath = xPathFactory.newXPath();

String expression = "//xs:element[@name='myapp']//xs:element[@name='content']";
NodeList nodeList = (NodeList) xPath.evaluate(expression,doc, XPathConstants.NODESET);
// nodeList is always empty...

这是我输入的 XSD 文件。

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://xmlns.oracle.com/cloud/adapter/nxsd/surrogate/request"
       xmlns="http://xmlns.oracle.com/cloud/adapter/nxsd/surrogate/request"
       elementFormDefault="qualified">
<xs:element name="myapp">
    <xs:complexType>
    <xs:sequence>
        <xs:element name="content">
            <xs:complexType>
                <xs:sequence>
                    <xs:element name="EmployeeID" type="xs:string" maxOccurs="1" minOccurs="0"/>
                    <xs:element name="EName" type="xs:string" maxOccurs="1" minOccurs="0"/>
                </xs:sequence>
            </xs:complexType>
        </xs:element>
        <xs:element name="attribute">
            <xs:complexType>
                <xs:sequence>
                    <xs:element name="item" type="xs:integer" maxOccurs="1" minOccurs="0"/>                        
                </xs:sequence>
            </xs:complexType>
        </xs:element>
    </xs:sequence>
    </xs:complexType>
</xs:element>
</xs:schema>

这是它的 XML

<?xml version="1.0" encoding="utf-8"?>
<myapp>
  <content>
    <EmployeeID>7856932</EmployeeID>
    <EName>John William</EName>
  </content>
  <attribute>
    <item>3922</item>
  </attribute>
</myapp>

您有 2 个选择:

  1. 从XPath表达式中去掉xs:(简单,但不推荐):

    String expression = "//element[@name='myapp']//element[@name='content']";
    

    请参阅 IDEONE 上的演示。

  2. 启用命名空间:

    factory.setNamespaceAware(true);
    
    xPath.setNamespaceContext(new NamespaceContext() {
        @Override
        public String getNamespaceURI(String prefix) {
            switch (prefix) {
                case "xs": return "http://www.w3.org/2001/XMLSchema";
                default:   return null;
            }
        }
        @Override
        public String getPrefix(String namespaceURI) {
            throw new UnsupportedOperationException();
        }
        @Override
        public Iterator<String> getPrefixes(String namespaceURI) {
            throw new UnsupportedOperationException();
        }
    });
    

    请参阅 IDEONE 上的演示。