【问题标题】:Java javax.xml.xpath.XPath evaluate does not return nodesJava javax.xml.xpath.XPath 评估不返回节点
【发布时间】:2021-08-14 19:24:45
【问题描述】:

我正在尝试过滤作为较大 GUI 程序一部分的 XSD 文档,但是我只想显示 XSD 文档的某些部分。我正在尝试使用 XPath 查询文档的所需部分:

XSD 文档是(较小的 sn-p,实际文档要大得多):

 <?xml version="1.0" encoding="UTF-8"?>
      <!-- PDS4 XML/Schema for Name Space Id:pds  Version:1.11.1.0 - Wed May 01 17:25:04 PDT 2019 -->
      <!-- Generated from the PDS4 Information Model Version 1.11.1.0 - System Build 9b -->
      <!-- *** This PDS4 product schema is an operational deliverable. *** -->
      <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://pds.abc.net/pds4/pds/v1"
        xmlns:pds="http://pds.abc.net/pds4/pds/v1"
        elementFormDefault="qualified"
        attributeFormDefault="unqualified"
        version="1.11.1.0">
     
      <xs:annotation>
        <xs:documentation>This XML schema file has been generated from the
          Information Model.</xs:documentation>
      </xs:annotation>
     
      <xs:element name="External_Reference" type="pds:External_Reference"> </xs:element>
      <xs:element name="Ingest_LDD" type="pds:Ingest_LDD"> </xs:element>
      <xs:element name="Internal_Reference" type="pds:Internal_Reference"> </xs:element>
      <xs:element name="Local_Internal_Reference" type="pds:Local_Internal_Reference"> </xs:element>
      <xs:element name="Product_AIP" type="pds:Product_AIP"> </xs:element>
      <xs:element name="Product_Ancillary" type="pds:Product_Ancillary"> </xs:element>
      <xs:element name="Product_Attribute_Definition" type="pds:Product_Attribute_Definition"> </xs:element>
      <xs:element name="Product_Browse" type="pds:Product_Browse"> </xs:element>
      <xs:element name="Product_Bundle" type="pds:Product_Bundle"> </xs:element>
      <xs:element name="Product_Class_Definition" type="pds:Product_Class_Definition"> </xs:element>
      <xs:element name="Product_Collection" type="pds:Product_Collection"> </xs:element>
      <xs:element name="Product_Context" type="pds:Product_Context"> </xs:element>
      <xs:element name="Product_DIP" type="pds:Product_DIP"> </xs:element>
      <xs:element name="Product_DIP_Deep_Archive" type="pds:Product_DIP_Deep_Archive"> </xs:element>
      <xs:element name="Product_Data_Set_PDS3" type="pds:Product_Data_Set_PDS3"> </xs:element>
      <xs:element name="Product_Document" type="pds:Product_Document"> </xs:element>
      <xs:element name="Product_File_Repository" type="pds:Product_File_Repository"> </xs:element>
      <xs:element name="Product_File_Text" type="pds:Product_File_Text"> </xs:element>
      <xs:element name="Product_Instrument_Host_PDS3" type="pds:Product_Instrument_Host_PDS3"> </xs:element>
      <xs:element name="Product_Instrument_PDS3" type="pds:Product_Instrument_PDS3"> </xs:element>
      <xs:element name="Product_Metadata_Supplemental" type="pds:Product_Metadata_Supplemental"> </xs:element>
      <xs:element name="Product_Mission_PDS3" type="pds:Product_Mission_PDS3"> </xs:element>
      <xs:element name="Product_Native" type="pds:Product_Native"> </xs:element>
      <xs:element name="Product_Observational" type="pds:Product_Observational"> </xs:element>
      <xs:element name="Product_Proxy_PDS3" type="pds:Product_Proxy_PDS3"> </xs:element>
      <xs:element name="Product_SIP" type="pds:Product_SIP"> </xs:element>
      <xs:element name="Product_SIP_Deep_Archive" type="pds:Product_SIP_Deep_Archive"> </xs:element>
      <xs:element name="Product_SPICE_Kernel" type="pds:Product_SPICE_Kernel"> </xs:element>
      <xs:element name="Product_Service" type="pds:Product_Service"> </xs:element>
      <xs:element name="Product_Software" type="pds:Product_Software"> </xs:element>
      <xs:element name="Product_Subscription_PDS3" type="pds:Product_Subscription_PDS3"> </xs:element>
      <xs:element name="Product_Target_PDS3" type="pds:Product_Target_PDS3"> </xs:element>
      <xs:element name="Product_Thumbnail" type="pds:Product_Thumbnail"> </xs:element>
      <xs:element name="Product_Update" type="pds:Product_Update"> </xs:element>
      <xs:element name="Product_Volume_PDS3" type="pds:Product_Volume_PDS3"> </xs:element>
      <xs:element name="Product_Volume_Set_PDS3" type="pds:Product_Volume_Set_PDS3"> </xs:element>
      <xs:element name="Product_XML_Schema" type="pds:Product_XML_Schema"> </xs:element>
      <xs:element name="Product_Zipped" type="pds:Product_Zipped"> </xs:element>
     
      <xs:element name="local_identifier" type="pds:local_identifier"> </xs:element>
      <xs:element name="logical_identifier" type="pds:logical_identifier"> </xs:element>
    
      <xs:complexType name="Agency">
        <xs:annotation>
          <xs:documentation>The Agency class provides a description of an
            entity that provides regional or national level neternance over
            nodes within the federated Planetary Data
            System.</xs:documentation>
        </xs:annotation>
        <xs:sequence>
          <xs:element name="name" type="pds:name" minOccurs="1" maxOccurs="1"> </xs:element>
          <xs:element name="description" type="pds:description" minOccurs="1" maxOccurs="1"> </xs:element>
        </xs:sequence>
      </xs:complexType>
    
      <xs:complexType name="Airborne">
        <xs:annotation>
          <xs:documentation>The Airborne class provides a description of the
            physical object that transports a platform by or through
            air.</xs:documentation>
        </xs:annotation>
        <xs:sequence>
          <xs:element name="name" type="pds:name" minOccurs="0" maxOccurs="1"> </xs:element>
          <xs:element name="type" type="pds:type" minOccurs="0" maxOccurs="1"> </xs:element>
          <xs:element name="description" type="pds:description" minOccurs="0" maxOccurs="1"> </xs:element>
        </xs:sequence>
      </xs:complexType>
    
      <xs:complexType name="Alias">
        <xs:annotation>
          <xs:documentation>The Alias class provides a single alternate name
            and identification for this product in this or some other
            archive or data system.</xs:documentation>
        </xs:annotation>
        <xs:sequence>
          <xs:element name="alternate_id" type="pds:alternate_id" minOccurs="0" maxOccurs="1"> </xs:element>
          <xs:element name="alternate_title" type="pds:alternate_title" minOccurs="0" maxOccurs="1"> </xs:element>
          <xs:element name="comment" type="pds:comment" minOccurs="0" maxOccurs="1"> </xs:element>
        </xs:sequence>
      </xs:complexType>
    
      <xs:complexType name="Alias_List">
        <xs:annotation>
          <xs:documentation>The Alias_List class provides a list of paired
            alternate names and identifications for this product in this or
            some other archive or data system.</xs:documentation>
        </xs:annotation>
        <xs:sequence>
          <xs:element name="Alias" type="pds:Alias" minOccurs="1" maxOccurs="unbounded"> </xs:element>
        </xs:sequence>
      </xs:complexType>
    
      <xs:complexType name="Archival_Information_Package">
        <xs:annotation>
          <xs:documentation>The Archival Information Package (AIP) class
            defines an Information Package consisting of the Content
            Information and the associated Preservation Description
            Information (PDI), which is preserved within an archive that
            conforms to the Open Archive Information System (OAIS) Reference
            Model.</xs:documentation>
        </xs:annotation>
        <xs:complexContent>
          <xs:restriction base="pds:Information_Package">
            <xs:sequence>
              <xs:element name="description" type="pds:description" minOccurs="1" maxOccurs="1"> </xs:element>
            </xs:sequence>
          </xs:restriction>
        </xs:complexContent>
      </xs:complexType>
    
      <xs:complexType name="Ingest_LDD">
        <xs:annotation>
          <xs:documentation>The Ingest_LDD class provides a form for
            collecting class and attribute definitions.</xs:documentation>
        </xs:annotation>
        <xs:sequence>
          <xs:element name="name" type="pds:name" minOccurs="1" maxOccurs="1"> </xs:element>
          <xs:element name="ldd_version_id" type="pds:ldd_version_id" minOccurs="1" maxOccurs="1"> </xs:element>
          <xs:element name="full_name" type="pds:full_name" minOccurs="1" maxOccurs="1"> </xs:element>
          <xs:element name="steward_id" type="pds:steward_id" minOccurs="1" maxOccurs="1"> </xs:element>
          <xs:element name="namespace_id" type="pds:namespace_id" minOccurs="1" maxOccurs="1"> </xs:element>
          <xs:element name="external_property_maps_id" type="pds:external_property_maps_id" minOccurs="0" maxOccurs="unbounded"> </xs:element>
          <xs:element name="comment" type="pds:comment" minOccurs="0" maxOccurs="1"> </xs:element>
          <xs:element name="last_modification_date_time" type="pds:last_modification_date_time" minOccurs="1" maxOccurs="1"> </xs:element>
          <xs:element name="DD_Attribute" type="pds:DD_Attribute" minOccurs="0" maxOccurs="unbounded"> </xs:element>
          <xs:element name="DD_Class" type="pds:DD_Class" minOccurs="0" maxOccurs="unbounded"> </xs:element>
          <xs:element name="DD_Rule" type="pds:DD_Rule" minOccurs="0" maxOccurs="unbounded"> </xs:element>
          <xs:element name="Property_Maps" type="pds:Property_Maps" minOccurs="0" maxOccurs="unbounded"> </xs:element>
        </xs:sequence>
      </xs:complexType>
    
      <xs:complexType name="Instrument">
        <xs:annotation>
          <xs:documentation>The Instrument class provides a description of a
            physical object that collects data.</xs:documentation>
        </xs:annotation>
        <xs:sequence>
          <xs:element name="name" type="pds:name" minOccurs="0" maxOccurs="1"> </xs:element>
          <xs:element name="Type_List_Area" type="pds:Type_List_Area" minOccurs="1" maxOccurs="1"> </xs:element>
          <xs:element name="type" type="pds:type" minOccurs="0" maxOccurs="unbounded"> </xs:element>
          <xs:element name="subtype" type="pds:subtype" minOccurs="0" maxOccurs="unbounded"> </xs:element>
          <xs:element name="model_id" type="pds:model_id" minOccurs="0" maxOccurs="1"> </xs:element>
          <xs:element name="naif_instrument_id" type="pds:naif_instrument_id" minOccurs="0" maxOccurs="1"> </xs:element>
          <xs:element name="serial_number" type="pds:serial_number" minOccurs="0" maxOccurs="1"> </xs:element>
          <xs:element name="description" type="pds:description" minOccurs="1" maxOccurs="1"> </xs:element>
        </xs:sequence>
      </xs:complexType>
    
      <xs:complexType name="Instrument_Host">
        <xs:annotation>
          <xs:documentation>The Instrument Host class provides a description
            of the physical object upon which an instrument is
            mounted.</xs:documentation>
        </xs:annotation>
        <xs:sequence>
          <xs:element name="name" type="pds:name" minOccurs="0" maxOccurs="1"> </xs:element>
          <xs:element name="instrument_host_version_id" type="pds:instrument_host_version_id" minOccurs="0" maxOccurs="1"> </xs:element>
          <xs:element name="version_id" type="pds:version_id" minOccurs="0" maxOccurs="1"> </xs:element>
          <xs:element name="type" type="pds:type" minOccurs="1" maxOccurs="1"> </xs:element>
          <xs:element name="naif_host_id" type="pds:naif_host_id" minOccurs="0" maxOccurs="1"> </xs:element>
          <xs:element name="serial_number" type="pds:serial_number" minOccurs="0" maxOccurs="1"> </xs:element>
          <xs:element name="description" type="pds:description" minOccurs="1" maxOccurs="1"> </xs:element>
        </xs:sequence>
      </xs:complexType>
     
    </xs:schema>

使用http://xpather.com/,我可以测试查询以选择例如“Injest_LDD”,使用以下任一方法:

//complexType[@name='Ingest_LDD']

或 //xs:complexType[@name='Ingest_LDD']

找到:

但是在 Java 中使用这些 XPath 查询模式返回,没有结果(XpathResult RETURNS NULL???):

     Document partialdoc = db.parse(task.getXsdFile().getFileObject());
                    System.out.println("Document file: " + task.getXsdFile().getFileObject());
                    
                    //ALSO TRIED: //xs:complexType[@name='Ingest_LDD']
                    String expression = "//xs:complexType[@name='" + localPart + "']";
    
                    System.out.println("DEBUG Class MainController, selectedXsdLocalPart(),expression:" + expression);
                    // Given the id, go to correct place in XSD to get all the parameters
                    XPath xpath = XPathFactory.newInstance().newXPath();
                    Node XpathResult = (Node) xpath.evaluate(expression, partialdoc, XPathConstants.NODE);
                    Element e;
                    //XpathResult RETURNS NULL???
                    if (XpathResult != null) {
                        StringBuilder sb = new StringBuilder();
                        for (int i = 0; i < XpathResult.getChildNodes().getLength(); i++) {
    
                            if (XpathResult.getChildNodes().item(i).getNodeType() == Node.ELEMENT_NODE) {
    
                                e = (Element) XpathResult.getChildNodes().item(i);
                                System.out.println(e.getNodeName() + " = " + e.getNodeValue());
                                sb.append(e.getNodeValue());
                            }
                        }
                        if (!sb.toString().equalsIgnoreCase("[xs:annotation: null][xs:sequence: null]") && sb.toString().length() > 0) {
                            viewToUpdate.getViewjTextAreaXsd().setText(sb.toString());
                        }
    
                    }

如何通过 Java 使用 XPath 在 XSD 中选择这些 complexType 元素?

赞赏。

【问题讨论】:

    标签: java xml xpath xsd


    【解决方案1】:

    当输入文档包含命名空间时,您必须提供一个 NamespaceContext 对象,以便 XPath 编译器和评估器能够解析命名空间前缀。在您的情况下,像这样的简单实现可能就足够了:

    static class MyNamespaceContext implements NamespaceContext {
    
        @Override
        public String getNamespaceURI(String prefix) {
            if (prefix.equals("xs"))
                return "http://www.w3.org/2001/XMLSchema";
            return null;
        }
    
        @Override
        public String getPrefix(String namespaceURI) {
            return null;
        }
    
        @Override
        public Iterator<?> getPrefixes(String namespaceURI) {
            return null;
        }
    }
    

    然后在计算任何表达式之前在 XPath 对象上设置上下文:

        xpath.setNamespaceContext(new MyNamespaceContext());
    

    然后您将能够使用此表达式选择正确的 complextType 节点:

    "//xs:complexType[@name='Ingest_LDD']"
    

    请注意,您的代码中使用的前缀可能与输入文档中使用的前缀不同;重要的是到命名空间 URI 的映射。

    另外:像 xpather 这样的工具通常是“智能的”,因为它们可以扫描输入文档并动态构建前缀到命名空间的 uri 映射,如果它们符合 XPath 2.0,它们通常还可以推断出“默认值” " 命名空间,XPath 1.0 中缺少的一个概念(我们仍然需要处理普通的 Java JDK)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-07
      • 1970-01-01
      • 2014-10-14
      相关资源
      最近更新 更多