使用XSD验证XML元素

使用XSD验证XML元素,xml,xsd,Xml,Xsd,我有以下XML: <?xml version="1.0" encoding="utf-8"?> <MainElement> <id>1</id> <name>John</name> <custom> <age>43</age> <sex>male</sex> </custom> </M

我有以下XML:

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

1.
约翰
43
男性的
和另一个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>

2.
戴夫
51
英格兰
伦敦

两个XML文件的主结构相同,只是
元素的实现不同。我已经有了一个XSD文件来检查元素,比如'id'和'name',其中
元素的类型是xs:anyType。是否可以创建另一个XSD文件,只验证
元素,而不查看存在的所有其他元素?

我将为两位客户演示。第一个XSD是基本的XSD,它应该捕获所有公共部分,除了我们引用但未定义的
自定义
;我们让它“摇摆不定”

下面是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-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将缺少的定义带入范围。现在,您可以验证每个供应商的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是涉及另一种模式语言的解决方案,它们各有优缺点。我认为以上内容至少可以帮助您理解一些选项…

对于XSD,您无法理解任何选项的字面含义

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

我赞成你使用import/include的方法。。这是一个清晰的定义,允许进一步扩展要求。。但您仍然应该知道任何元素的可能名称

虽然这不是必需的,但您需要知道使用
序列
选择
的另一种方法,以实现您的需求,仅使用一个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>


这可能暂时对您没有用处,但将来可能会有用。

您必须回答的第一件事是如何确定应该获得哪个
自定义
元素。如果您计划使用相同的标记,但使用不同的内容模型,那么在XSD 1.0中,如果不自定义XML预处理和动态加载适当的XSD(这称为悬挂定义),或者不使用附加到自定义元素的xsi:type属性,就无法做到这一点。如果“custom”元素指的是任何命名的元素,那么事情可能会变得更简单或更复杂,这取决于您希望设置的约束。如果您可以添加更多详细信息,自定义元素将始终具有名称“custom”,并且是可选元素。例如,有三个客户将向我发送XML文件,根据客户的不同,我需要使用相应的XSD文件来验证“custom”元素中的所有子元素。对于所有三个客户,我将使用相同的XSD来验证xml文件的其余部分,如“id”和“name”元素。你知道这只能用XSD实现,还是我需要使用其他技术?
Error occurred while loading [file:///.../validate-xml-element-with-xsd-2.xsd], line 9 position 10.
The 'custom' element is not declared.
<?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>