1

我有看起来像这样的xml文件

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

我想根据属性“名称”中的值按模式验证元素文本。也就是说,如果属性的值为“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>
4

1 回答 1

1

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

XSD 被设计为主要(并且在简单的情况下仅)基于元素的名称来验证元素。如果您有三种不同的验证逻辑,那么您最好告诉 XSD 验证器存在三种类型的元素(可能命名为 simple_meta、complex_meta 和 test_date),而不是难以置信地声称只有一种类型的元素。使用公共基本类型使三个元素的类型之间的关系明确,或使用公共替换组将三个元素类型本身联系起来。

如果您真的必须这样做,或者如果您真的知道自己在做什么并且想要这样做(我不确定这种组合是否可行,但我会尝试在这里保持开阔的视野),您的基本选择是:

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

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

  • 使用 XSD 1.1 和断言

或者留下 XSD:

  • 使用 Schematron 和断言

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

于 2013-11-12T02:53:38.310 回答