创建具有未绑定数量的元素的XML-Schema

时间:2014-08-22 09:10:15

标签: xml xsd schema

我有一个具有以下结构的XML -Data

<Data>
   <Name />
   <Code />
   <Prodprop>
      <key />
      <value />
   </Prodprop>
   <Prodprop>
      <key />
      <value />
   </Prodprop>
   <Tag />
   <Blub />
</Data>

我需要一个用于此数据的XML Schema,但标签可以按任何顺序出现,但所有Prodprop都是连续的。所有其他元素只需要一次或最多一次因此以下数据也是有效的。

 <Data>
       <Code />
       <Name />
       <Tag />
       <Prodprop>
          <key />
          <value />
       </Prodprop>
       <Prodprop>
          <key />
          <value />
       </Prodprop>
    </Data>

这是我的(我知道这是不可能的)Schema。

    <xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
  <xsd:element name="Data" type="DataType" /> 
  <xsd:complexType name="DataType">
        <xsd:all>
          <xsd:element name="Name" type="xsd:string" />
          <xsd:element name="Code" type="xsd:string" />
          <xsd:element maxOccurs="unbounded" name="Prodprop" type="ProdpropType" />
          <xsd:element name="Tag" type="xsd:string" />
          <xsd:element name="Blub" type="xsd:string" />
        </xsd:all> 
   </xsd:complexType>
    <xsd:complexType name="ProdpropType">
        <xsd:sequence>
          <xsd:element name="key" type="xsd:string" />
          <xsd:element name="value" type="xsd:string" />
        </xsd:sequence> 
       </xsd:complexType> 
  </xsd:schema>

是否有可能为此szenario提供有效的xml架构?

2 个答案:

答案 0 :(得分:3)

我认为如果不在xpath中使用复杂的东西,你就不可能做到这一点。

@C。 M. Sperberg-McQueen是对的。有可能,但是,如果您不将要求更改为更简单的要求,则必须提供标记可能具有的所有可能的组合顺序。尽管这个解决方案完全合法,但这个解决方案非常复杂和麻烦。

接近你所描述的一个好主意是将Prodprop元素包装在另一个元素中,例如: ProdpropList。使用这种方法,您可以将所有Prodprop项目作为批处理,无论何时移动,它们都会作为一个整体移动。

您可以在线测试here

检查一下: 的 XSD

<xsd:schema attributeFormDefault="unqualified"
    elementFormDefault="qualified" version="1.0"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:element name="Data" type="DataType" />
    <xsd:complexType name="DataType">
        <xsd:all>
            <xsd:element name="Name" type="xsd:string" />
            <xsd:element name="Code" type="xsd:string" />
            <xsd:element name="ProdpropList" type="ProdpropListType" />
            <xsd:element name="Tag" type="xsd:string" />
            <xsd:element name="Blub" type="xsd:string" />
        </xsd:all>
    </xsd:complexType>

    <xsd:complexType name="ProdpropListType">
        <xsd:sequence>
            <xsd:element name="Prodprop" type="ProdpropType"
                maxOccurs="unbounded" />
        </xsd:sequence>
    </xsd:complexType>

    <xsd:complexType name="ProdpropType">
        <xsd:sequence>
            <xsd:element name="key" type="xsd:string" />
            <xsd:element name="value" type="xsd:string" />
        </xsd:sequence>
    </xsd:complexType>
</xsd:schema>

<强> XML

<Data>
    <Name />
    <Code />
    <ProdpropList>
        <Prodprop>
            <key />
            <value />
        </Prodprop>
        <Prodprop>
            <key />
            <value />
        </Prodprop>
    </ProdpropList>
    <Tag />
    <Blub />
</Data>

答案 1 :(得分:2)

如果我正确理解您的问题,您希望Data元素的内容包含

  • 零个或多个(?或一个或多个?)Prodprop元素的序列
  • 前面或后面跟着任意数量的名为Name,Code,Tag,Blub,Foo,Bar,Baz ......的元素,每个元素必须出现一次,其中一些是可选的

声称这是不可能的答案是不正确的。您描述的内容模型并非不可能;它显然是一种常规语言,并且可以用XSD内容模型清楚地表达。这肯定是可能的;然而,它非常不方便。

要满足您声明的要求,您需要为您描述的语言(允许的子级序列)创建正则表达式,然后将该正则表达式写为XSD内容模型。 XSD的不切实际的尝试是保持内容模型的简单性,这使得任务变得复杂。通过要求它们具有确定性,但您可以在其他StackOverflow问题hereherehere中找到有关如何处理的说明(最后一个问题)是关于DTD,而不是XSD,但适用相同的原则。)

如果您不想拥有复杂的内容模型,那么您可以通过修改您的要求来实现更简单的内容,以便更好地适应您的验证技术。

  • 正如@alkis已经建议的那样,你可以将Prodprop元素包装在一个包装元素中,然后使用一个简单的XSD 1.0 all组。
  • 您可以为子项指定所需的顺序,除非它们出现的顺序包含您的应用程序的一些信息。 (如果序列没有信息,则不需要允许它变化。)