【问题标题】:Java XPath: Can't find an element [duplicate]Java XPath:找不到元素[重复]
【发布时间】:2018-05-17 13:47:26
【问题描述】:

我无法从架构中找到第一个元素 simpleType

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified">
    <xs:simpleType name="IdType">
        <xs:annotation>
            <xs:documentation>Уникальный идентификатор (ключ) объекта в АИС контрагента</xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:token">
            <xs:minLength value="1"/>
            <xs:maxLength value="60"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="DateType">
        <xs:annotation>
            <xs:documentation>Дата</xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:date">
            <xs:minInclusive value="1900-01-01"/>
            <xs:maxExclusive value="2100-01-01"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="DateTimeType">
        <xs:annotation>
            <xs:documentation>Дата и время</xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:dateTime">
            <xs:minInclusive value="1900-01-01T00:00:00"/>
            <xs:maxExclusive value="2100-01-01T00:00:00"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="String_1_1000">
        <xs:annotation>
            <xs:documentation>Строка длиной от 1 до 1000 символов</xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:string">
            <xs:minLength value="1"/>
            <xs:maxLength value="1000"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="DocumentNumberType">
        <xs:annotation>
            <xs:documentation>Номер документа</xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:string">
            <xs:minLength value="1"/>
            <xs:maxLength value="25"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="OrganizationCodeType">
        <xs:annotation>
            <xs:documentation>Код организации</xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:string">
            <xs:minLength value="1"/>
            <xs:maxLength value="32"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="DepartmentCodeType">
        <xs:annotation>
            <xs:documentation>Код подразделения</xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:string">
            <xs:minLength value="1"/>
            <xs:maxLength value="32"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="CaseNumberType">
        <xs:annotation>
            <xs:documentation>Номер дела</xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:string">
            <xs:minLength value="1"/>
            <xs:maxLength value="25"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="DocumentDataType">
        <xs:annotation>
            <xs:documentation>Тип документа электронного документооборота</xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:string">
            <xs:minLength value="1"/>
            <xs:maxLength value="32"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="StateIdType">
        <xs:annotation>
            <xs:documentation>Состояние документа</xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:string">
            <xs:enumeration value="90"/>
            <xs:enumeration value="91"/>
            <xs:enumeration value="92"/>
            <xs:enumeration value="93"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="AttachmentFilenameType">
        <xs:annotation>
            <xs:documentation>Имя файла вложения</xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:ID">
            <xs:maxLength value="1024"/>
        </xs:restriction>
    </xs:simpleType>
</xs:schema>

这就是我尝试解析 xml 的方式:

public Node getFirstByExpression(final String expr) {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setNamespaceAware(false);

    try {

         DocumentBuilder builder = factory.newDocumentBuilder();
         document = builder.parse(source);
         document.getDocumentElement().normalize();

         XPathFactory factory = XPathFactory.newInstance();
         XPath xPath = factory.newXPath();
         NodeList nodeList = null;

         XPathExpression expression = xPath.compile(expr);
         nodeList = (NodeList) expression.evaluate(document, XPathConstants.NODESET);
         return nodeList.getLength() == 0 ? null : nodeList.item(0);

    } catch (Exception ex) {
            log.error(ex);
            return null;
    }
}

因此,如果将参数simpleType 传递给方法nodeList 的长度等于0,并且该方法返回null。这些测试也可能对您有所帮助:

assert parser.getFirstByExpression("schema") != null; // true

assert parser.getFirstByExpression("/schema") != null; // true

assert parser.getFirstByExpression("//schema") != null; // false, seems it must be true

assert parser.getFirstByExpression("simpleType") != null; // false, need to be true

更新

添加测试:

assert parser.getFirstByExpression("//simpleType") != null; // false
assert parser.getFirstByExpression("/schema/simpleType") != null; // true

我真正需要的是在架构中的任意位置找到simpleType

【问题讨论】:

  • 如果第二个断言为真,第三个断言也应该为真,对吧?看起来不对。
  • @kutschkem 是的,它也必须是真的
  • 请尝试factory.setNamespaceAware(true)

标签: java xml xpath


【解决方案1】:

没有前导斜杠的 XPath 表达式是从当前节点开始的相对路径。在您的情况下,这是根节点,因此 simpleType/simpleType 是等效的,而不是您想要的。你想要的是

//simpleType 或者 /schema/simpleType

【讨论】:

  • 一些 XPath 教程说,如果没有前导斜杠,则会找到文档中的所有节点,而不仅仅是当前节点的子节点(也称为上下文节点)。但如果我正确理解w3.org/TR/2010/REC-xpath20-20101214/#abbrev,情况并非如此,只会选择孩子。
猜你喜欢
  • 2018-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-07
  • 2018-05-29
  • 1970-01-01
相关资源
最近更新 更多