我有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>
答案 0 :(得分:1)
简短的回答是:不要那样做。
XSD旨在主要基于元素的名称(以及在简单的情况下仅使用)来验证元素的名称。如果您有三种不同的验证逻辑,那么您最好告诉XSD验证器有三种类型的元素(命名为,simple_meta,complex_meta和test_date),而不是令人难以置信地声称只有一种类型的元素。使用公共基类型使三个元素的类型之间的关系显式化,或使用公共替换组来关联三个元素类型本身。
如果你真的必须这样做,或者如果你真的知道自己在做什么并且想要这样做(我不确定这种组合是否可行,但我会尝试在这里做一些宽容的事),你的基本选择是:
在实例中使用xsi:type
来指定实例中每个元素的类型(大致类似于您的name
属性,但命名模式中声明的类型)
使用XSD 1.1和条件类型赋值
使用XSD 1.1和断言
或者让XSD落后:
使用Schematron和断言
使用RelaxNG并将属性的不同值写入内容模型