xsd中的元素名称相同,但验证逻辑不同

时间:2013-03-20 07:10:35

标签: xml xsd xsd-validation

我有xml文件,好像是

<doc>
 <field name="simple_meta">book</field>
 <field name="complex_meta">journal</field>
 <field name="text_date">some text</field>
</doc>

我想根据属性“name”中的值按模式验证元素文本。也就是说,如果属性的值是“simple_meta”,我想进行“simpleRestriction”验证,如果“complex_meta”进行“complexRestriction”验证。问题是我无法在同一节点下定义具有相同名称的元素。有人可以帮我解决这个问题吗?

<xs:schema ......>
   <xs:simpleType name="simpleRestriction">
      <xs:restriction base="xs:string">
         <xs:maxLength value="20"/>
      </xs:restriction>
   </xs:simpleType>
   <xs:simpleType name="complexRestriction">
      <xs:restriction base="xs:string">
         <xs:maxLength value="10"/>
         <xs:pattern value="([\w])*"/>
      </xs:restriction>
   </xs:simpleType>

   <xs:element name="str">
      <xs:complexType>
         <xs:simpleContent>
            <xs:extention base="simpleRestriction">
               <xs:attribute name="name">
                  <xs:simpleType>   
                     <xs:restriction base="xs:string">  
                        <xs:pattern value="simple_meta"/>
                     </xs:restriction>
                  </xs:simpleType>   
               </xs:attribute>
            </xs:extention>
         </xs:simpleContent>
      </xs:ComplexType>
   </xs:element>
   <xs:element name="str">
      <xs:complexType>
         <xs:simpleContent>
            <xs:extention base="complexRestriction">
               <xs:attribute name="name">
                  <xs:simpleType>   
                     <xs:restriction base="xs:string">  
                        <xs:pattern value="complex_meta"/>
                     </xs:restriction>
                  </xs:simpleType>   
               </xs:attribute>
            </xs:extention>
         </xs:simpleContent>
      </xs:ComplexType>
   </xs:element>
</xs:schema>

1 个答案:

答案 0 :(得分:1)

简短的回答是:不要那样做。

XSD旨在主要基于元素的名称(以及在简单的情况下仅使用)来验证元素的名称。如果您有三种不同的验证逻辑,那么您最好告诉XSD验证器有三种类型的元素(命名为,simple_meta,complex_meta和test_date),而不是令人难以置信地声称只有一种类型的元素。使用公共基类型使三个元素的类型之间的关系显式化,或使用公共替换组来关联三个元素类型本身。

如果你真的必须这样做,或者如果你真的知道自己在做什么并且想要这样做(我不确定这种组合是否可行,但我会尝试在这里做一些宽容的事),你的基本选择是:

  • 在实例中使用xsi:type来指定实例中每个元素的类型(大致类似于您的name属性,但命名模式中声明的类型)

  • 使用XSD 1.1和条件类型赋值

  • 使用XSD 1.1和断言

或者让XSD落后:

  • 使用Schematron和断言

  • 使用RelaxNG并将属性的不同值写入内容模型