3

我有以下 XML:

<?xml version="1.0" encoding="utf-8"?>
<MainElement>
    <id>1</id>
    <name>John</name>
    <custom>
        <age>43</age>
        <sex>male</sex>
    </custom>
</MainElement>

还有另一个 XML 文件:

<?xml version="1.0" encoding="utf-8"?>
<MainElement>
    <id>2</id>
    <name>Dave</name>
    <custom>
        <age>51</age>
        <county>England</country>
        <city>London</city>
    </custom>
</MainElement>

两个 XML 文件的主要结构相同,只是<custom>元素具有不同的实现。我已经有一个 XSD 文件来检查元素<custom>类型为 xs:anyType 的“id”和“name”等元素。是否可以创建另一个 XSD 文件,它只验证<custom>元素而不查看存在的所有其他元素?

4

2 回答 2

0

我将为两个客户说明。第一个 XSD 是应该捕获所有公共部分的基础 XSD,除了custom我们引用但未定义的部分;我们让它“悬空”。

下面是common.xsd:

<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="MainElement">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="id" type="xsd:unsignedByte" />
        <xsd:element name="name" type="xsd:string" />
        <xsd:element ref="custom"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

然后我们开始为每个custom. 对于第一个 XML (custom-1.xsd):

<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:element name="custom">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="age" type="xsd:unsignedShort"/>
                <xsd:element name="sex" type="xsd:string"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

对于第二个,custom-2.xsd:

<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:element name="custom">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="age" type="xsd:unsignedShort"/>
                <xsd:element name="country" type="xsd:string"/>
                <xsd:element name="city" type="xsd:string"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

然后,您必须通过适当地加载 XSD 为每个客户创建一个模式集:第一组将包括 common + custom-1,然后是 common + custom-2,等等。

这就是我使用 QTAssistant “可视化”这些集合的方式:

在此处输入图像描述

当然,它本身Common是无效的。

Error occurred while loading [file:///.../validate-xml-element-with-xsd-2.xsd], line 9 position 10.
The 'custom' element is not declared.

但是,每个其他集合都是有效的,因为集合中的附加 XSD 会将缺少的定义纳入范围。现在您可以验证每个供应商的 XML 及其关联集。您可以维护跨供应商的通用定义的完整性,因为您确实共享一个通用 XSD,并且您可以使用悬空定义摆脱 XSD 1.0 中的“限制”。我认为这并不是真正的限制;这可能是一种“不那么优雅”的方法......

从处理的角度来看,您需要像供应商一样多次编译和加载通用 XSD 的开销。

如果这成为一种负担,您还可以使用另一种策略,一旦预处理您的 XML 得到回报。您可以保留custom定义为 anyType,甚至可以将其替换为 xsd:any。一旦验证了公共节点,就提取节点(XSLT 或 DOM API 或 DOM 节点阅读器之上的验证阅读器等)并使用适当的 XSD 独立验证它。

后一种方法的优点是在 XSD 方面不会有任何开销。当然,权衡可能会增加处理中的足迹。

XSD 1.1、XSD 1.0 + Schematron、RelaxNG 是涉及另一种模式语言的解决方案,它们各有优缺点。我认为以上内容至少应该可以帮助您了解您拥有的一些选项...

于 2012-11-02T01:09:32.077 回答
0

使用 XSD,您不能使用 ANY 的字面意思!

因此,您需要以一种或其他方式声明所有作为 XML 的一部分 .. 的内容。

我对您使用 import/include 的方法表示赞赏..这是一个干净的方法,可以进一步扩展要求..但您仍然应该知道 ANY 元素的可能名称..

虽然这不是必需的,但您会被要求了解另一种使用方法Sequencechoice满足您的要求,只需一个 XSD

这是验证 XML1 和 XML2 的代码:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="MainElement">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="id" type="xs:unsignedByte" />
        <xs:element name="name" type="xs:string" />
        <xs:element name="custom">
          <xs:complexType>
            <xs:sequence>
              <xs:choice>
                <xs:element name="age" type="xs:unsignedByte" />
              </xs:choice>
              <xs:choice>
                <xs:sequence>
                  <xs:element name="sex" type="xs:string" />
                </xs:sequence>
                <xs:sequence>
                  <xs:element name="country" type="xs:string"/>
                  <xs:element name="city" type="xs:string"/>
                </xs:sequence>
              </xs:choice>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

这可能暂时对您没有用,但将来可能对您有用..

于 2012-11-26T08:43:19.347 回答