如何根据属性值执行 XML 验证

how to carry out XML Validation based on Attribute value

面临 XML 验证问题。我的 XML 数据是这样的

<Sections>
          <Section Id="DateAndTimeSection" Enable="True" >
            <Column Id="Date" Format="YYYYMMDD" />
            <Column Id="Time" Format="HHMMSS" />
          </Section>
          <Section Id="ComponentIdSection" Enable="True" >
            <Column Id="ComponentId" Title="COUNTER" Enable="True" />
          </Section>
    </Sections>

我需要根据“Section”元素的“Id”属性验证XML文档。

如果sectionId值为DateAndTimeSection那么它应该只支持Column的使用 ID 的 DateTime。如果存在除上述以外的任何 Columns,即。使用 Id 值而不是 DateTime 它应该被通知为无效 XML .

示例:有效 XML

<Section Id="DateAndTimeSection" Enable="True" >
        <Column Id="Date" Format="YYYYMMDD" />
        <Column Id="Time" Format="HHMMSS" />
</Section>

无效XML

<Section Id="DateAndTimeSection" Enable="True" >
         <Column Id="Date" Format="YYYYMMDD" />
         <Column Id="Example" Format="YYYY" />
</Section>

我尝试了 XML 基于架构和 Schematron 的验证。

您可以使用 XSD 1.1 中的 "conditional type assignment"(也称为 "type alternatives")功能实现此目的。 XML Schema 1.0.

无法完成

类型替代允许模式表明元素的类型取决于元素属性的值。

XSD 1.1 在 Altova、Saxon 和 Xerces 中实现,但例如在 Microsoft 的 XSD 处理器中未实现。

XSD(限于感兴趣的部分和草稿):

<xs:element name="Sections">
    <xs:complexType>
        <xs:sequence>
            <!-- other content?-->
            <xs:element ref="Section" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

<xs:element name="Section">
    <xs:complexType>

        <xs:sequence>
            <!-- other content?-->
            <xs:element ref="Column" maxOccurs="unbounded"/>
        </xs:sequence>

        <xs:attribute name="Id" use="required" type="xs:string"/>
        <!--         other attribute definitions   -->
    </xs:complexType>
</xs:element>

<xs:element name="Column">
    <xs:complexType>
        <!-- other content or empty?-->
        <xs:attribute name="Id" use="required" type="xs:string"/>
        <!--         other attribute definitions   -->
    </xs:complexType>
</xs:element>

示意图:

<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2" xmlns:sqf="http://www.schematron-quickfix.com/validator/process">
    <sch:pattern>
        <!-- check only Columns in DateAndTimeSections-->
        <sch:rule context="Section[@Id = 'DateAndTimeSection']/Column">
            <!-- Check that ID is Date or Time -->
            <sch:assert test="@Id = 'Date' or @Id = 'Time'">Columns in DateAndTimeSections should have the ID Date or Time.</sch:assert>
        </sch:rule>
    </sch:pattern>
</sch:schema>