【问题标题】:Error on validating XML at xsi:type value在 xsi:type 值处验证 XML 时出错
【发布时间】:2019-03-17 22:12:22
【问题描述】:

我有这个 XML,我一直在 HTTP 请求中使用它

<?xml version="1.0"?>
<updateList xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="urn:messages_namespace" xmlns:listRel="urn:relationships_namespace" xmlns:pc="urn:core_namespace">
  <pc:record xsi:type="listRel:Customer" internalId="46" xmlns:listRel="urn:relationships_namespace">
    <listRel:companyName>T Tax</listRel:companyName>
  </pc:record>
  <pc:record xsi:type="listRel:Customer" internalId="44" xmlns:listRel="urn:relationships_namespace">
    <listRel:companyName>S Tax</listRel:companyName>
  </pc:record>
  <pc:record xsi:type="listRel:Customer" internalId="45" xmlns:listRel="urn:relationships_namespace">
    <listRel:companyName>K Tax</listRel:companyName>
  </pc:record>
</updateList>

我为这个 XML 生成的 XSD 看起来像这样,

<xs:element name="updateList">
<xs:complexType>
  <xs:sequence>
    <xs:element maxOccurs="unbounded" name="record">
      <xs:complexType>
        <xs:sequence>
          <xs:element name="companyName" type="xs:string" />
        </xs:sequence>
        <xs:attribute name="internalId" type="xs:unsignedByte" use="required" />
      </xs:complexType>
    </xs:element>
  </xs:sequence>
</xs:complexType>

但是当我尝试针对生成的架构验证相同的 XML 时,我收到了这个错误 -

    This is an invalid xsi:type 'urn:relationships_namespace:Customer'.

对于 XML 中的所有三个客户记录。但令人困惑的是,HTTP 请求在没有任何更改的情况下工作正常。将不胜感激这方面的任何帮助。卡了这么久。

P.S.- 还检查了各种 StackOverFlow 答案,但到目前为止没有一个有效。

【问题讨论】:

    标签: xml xsd xmlhttprequest xsd-validation


    【解决方案1】:

    XSD 是错误的。在带有 targetNamespace urn:core_namespace 的 XSD 中,您应该为您的记录元素定义一个命名类型,例如Record:

    让我们将此架构文件称为core.xsd 以供以后参考:

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <!-- EDIT 2019-03-17: added missing xmlns -->
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="urn:core_namespace" targetNamespace="urn:core_namespace" elementFormDefault="qualified">
      <xs:complexType name="Record">
            <!-- EDIT 2019-03-17: moved 'companyName' element to Customer type in relationships.xsd -->
            <xs:attribute name="internalId" type="xs:unsignedByte" use="required" />
      </xs:complexType>
      <!-- EDIT 2019-02-28: ADDED 'record' element-->
      <xs:element name="record" type="Record" />
    </xs:schema>
    

    在另一个带有 targetNamespcae urn:relationships_namespace 的 XSD 中,您应该导入之前的 XSD 并将 Customer 类型定义为 Record 类型的扩展:

    让我们将此架构文件称为 relationships.xsd 以供以后参考:

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"  targetNamespace="urn:relationships_namespace" 
    xmlns:pc="urn:core_namespace" elementFormDefault="qualified">
      <xs:import namespace="urn:core_namespace" schemaLocation="core.xsd"/>
      <xs:complexType name="Customer">
        <xs:complexContent>
          <xs:extension base="pc:Record">
            <!-- EDIT 2019-03-17: added 'companyName' element (moved from Record type in core.xsd) -->
            <xs:sequence>
              <xs:element name="companyName" type="xs:string" />
            </xs:sequence>
          </xs:extension>
        </xs:complexContent>
      </xs:complexType>
    </xs:schema>
    

    --EDIT 2019-02-28:在下面添加了架构--

    以及定义updateList 元素的最终架构。

    让我们将此架构文件称为 messages.xsd 以供以后参考:

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"  targetNamespace="urn:messages_namespace" 
    xmlns:pc="urn:core_namespace" elementFormDefault="qualified">
      <xs:import namespace="urn:core_namespace" schemaLocation="core.xsd"/>
      <xs:element name="updateList">
        <xs:complexType>
          <xs:sequence>
            <xs:element ref="pc:record" maxOccurs="unbounded" />
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:schema>
    

    对于schemaLocations,这是假设所有 XSD 都在同一个文件夹中,否则相应地更改 schemaLocations。

    编辑 2019-03-17

    此外,请修复您的 XML 以确保 updateList 元素在 urn:messages_namespace 中:xmlns:m="urn:messages_namespace" 替换为 xmlns="urn:messages_namespace"(默认命名空间)。

    这是固定的 XML,假设它在文件 updateList.xml 中:

    <?xml version="1.0"?>
    <updateList xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:messages_namespace" xmlns:listRel="urn:relationships_namespace" xmlns:pc="urn:core_namespace">
      <pc:record xsi:type="listRel:Customer" internalId="46" xmlns:listRel="urn:relationships_namespace">
        <listRel:companyName>T Tax</listRel:companyName>
      </pc:record>
      <pc:record xsi:type="listRel:Customer" internalId="44" xmlns:listRel="urn:relationships_namespace">
        <listRel:companyName>S Tax</listRel:companyName>
      </pc:record>
      <pc:record xsi:type="listRel:Customer" internalId="45" xmlns:listRel="urn:relationships_namespace">
        <listRel:companyName>K Tax</listRel:companyName>
      </pc:record>
    </updateList>
    

    这是一段 Java 代码示例,并说明了如何使用 XML 模式文件验证 XML(适用于 Java 8 以及工作目录中的所有 XSD 和 XML 文件,将其放在类的 main 方法中如果你想测试它):

    // XSD compiler
    final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
    // Load all XSD files starting with core.xsd
    final Source coreXsd = new StreamSource(new File("core.xsd"));
    final Source relationshipsXsd = new StreamSource(new File("relationships.xsd"));
    final Source messagesXsd = new StreamSource(new File("messages.xsd"));
    final Source[] schemaSources = { coreXsd, relationshipsXsd, messagesXsd };
    // Compile the final schema for validation
    final Schema schema = schemaFactory.newSchema(schemaSources);
    // XML to be validated
    final Source xml = new StreamSource(new File("updateList.xml"));
    // Validate
    final Validator validator = schema.newValidator();
    validator.validate(xml);
    System.out.println(xml.getSystemId() + " is valid.");
    

    【讨论】:

    • 感谢@cyril 的回复。尝试了您的解决方案,但现在我的 XML 中出现无效的子元素错误,用于 pc:record 具有“listRel:CompanyName”并说预期的元素是 pc:companyName 但命名空间甚至没有这个元素定义。能否请你帮忙?您的意思是针对您提到的将 tns 设置为 "urn:relationships_namespace" 的第二个模式进行验证吗?但这对 updateList 的元素没有任何引用
    • 是的,我的意思是使用第二个模式进行验证(它已经导入了第一个模式)。是的,我没有在我的 xsd 中包含“updateList”,因为您的 XML 没有为它声明名称空间,所以我不知道它应该是哪个名称空间。 'updateList' 元素的命名空间是什么? urn:core_namespace?如果我知道,我可以更新我的答案。 XML 应该像这样开始:&lt;updateList xmlns="the_namespace_for_updateList" ...&gt; ...
    • 而且我应该在我的问题本身中指定,我上面显示的 XSD 与 urn:messages_namespace 具有相同的 tns
    • 好的,所以你的 XML 也是错误的。应该是&lt;m:updateList xmlns:m="urn:messages_namespace" ...&gt; ...&lt;updateList xmlns="urn:messages_namespace" ...&gt; ...(不带前缀)
    • 我已将“urn:messages_namespace”的模式与 updateList 和元素“记录”添加到“core_namespace”模式中,因为它在元素 ref 中使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-13
    • 2011-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多