使用XSD验证XML ...但仍允许可扩展性

时间:2010-07-27 20:46:22

标签: xml xsd xml-validation

也许是我,但看起来如果你有XSD

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="User">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="GivenName" />
                <xs:element name="SurName" />
            </xs:sequence>
            <xs:attribute name="ID" type="xs:unsignedByte" use="required" />
        </xs:complexType>
    </xs:element>
</xs:schema>

定义此文档的架构

<?xml version="1.0" encoding="utf-8" ?>
<User ID="1">
    <GivenName></GivenName>
    <SurName></SurName>
</User>

如果您添加了另一个元素,例如EmailAddress,并且混合了订单

,则无法验证
<?xml version="1.0" encoding="utf-8" ?>
<User ID="1">
    <SurName></SurName>
    <EmailAddress></EmailAddress>
    <GivenName></GivenName>
</User>

我不想将EmailAddress添加到文档中,并将其标记为可选。

我只想要一个XSD来验证文档必须满足的最低要求。

有办法做到这一点吗?

编辑:

marc_s在下面指出,您可以在xs:any内使用xs:sequence来允许更多元素,遗憾的是,您必须维护元素的顺序。

或者,我可以使用不强制执行元素顺序的xs:all,但唉,不允许我在其中放置xs:any

5 个答案:

答案 0 :(得分:53)

答案 1 :(得分:6)

在阅读了 marc_s 的答案以及您在评论中的讨论后,我决定添加一点。

在我看来 您的问题没有完美的解决方案 Chad 。如何在XSD中实现可扩展内容模型有一些方法,但我所知的所有实现都有一些限制。因为您没有写过计划使用可扩展XSD的环境,所以我只推荐一些可能有助于您选择在您的环境中实现的方式的链接:

  1. http://www.xfront.com/ExtensibleContentModels.html(或http://www.xfront.com/ExtensibleContentModels.pdf)和http://www.xfront.com/VariableContentContainers.html
  2. http://www.xml.com/lpt/a/993(或http://www.xml.com/pub/a/2002/07/03/schema_design.html
  3. http://msdn.microsoft.com/en-us/library/ms950793.aspx

答案 2 :(得分:4)

您应该能够使用<xs:any>元素扩展架构以实现可扩展性 - 有关详细信息,请参阅W3Schools

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="User">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="GivenName" />
                <xs:element name="SurName" />
                <xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax" />
            </xs:sequence>
            <xs:attribute name="ID" type="xs:unsignedByte" use="required" />
        </xs:complexType>
    </xs:element>
</xs:schema>

当您添加processContents="lax"时,.NET XML验证应该会成功。

有关详细信息,请参阅MSDN docs on xs:any

更新:如果您需要更多灵活性和不太严格的验证,您可能需要查看为您的XML定义架构的其他方法 - 类似RelaxNG。 XML Schema - 故意 - 相当严格的规则,所以也许这只是当前工作的错误工具。

答案 3 :(得分:1)

嗯,你总是可以使用DTD :-),除了DTD还规定了订购。使用“无序”语法进行验证非常昂贵。您可以使用xsd:choice并且min和max会发生但是它可能也会被禁止。您还可以编写XSD扩展/派生模式。

你提出问题的方式看起来你根本不想要XSD。你可以加载它,然后用XPath验证你想要的最低限度,但只是抗议XSD,它成为全方位现有标准多少年后真的,真的不会让你到任何地方。

答案 4 :(得分:1)

RelaxNG将简洁地解决这个问题,如果你可以使用它。确定性不是模式的必要条件。您可以将RNG或RNC架构转换为XSD,但在这种情况下它将近似。这对你的使用是否足够好取决于你。

此案例的RNC架构是:

start = User
User = element User {
   attribute ID { xsd:unsignedByte },
   ( element GivenName { text } &
     element SurName { text } &
     element * - (SurName | GivenName) { any })
}

any = element * { (attribute * { text } | text | any)* }

任何规则都匹配任何格式良好的XML片段。因此,这将要求User元素包含任何顺序包含文本的GivenName和SurName元素,并允许包含几乎任何内容的任何其他元素。