XSD 1.1在子元素上断言

时间:2015-09-19 01:27:43

标签: xml xsd

我认为这个应该正在运作......但事实并非如此!这是我的XSD:

 <xsd:schema targetNamespace="http://www.loc.gov/MARC21/slim" xmlns="http://www.loc.gov/MARC21/slim"
        xmlns:xerces="http://xerces.apache.org" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.1" xml:lang="en">

        <xsd:element name="record" type="recordType" nillable="true" id="record.e"/>

        <xsd:element name="collection" type="collectionType" nillable="true" id="collection.e"/>

        <xsd:complexType name="collectionType" id="collection.ct">
            <xsd:sequence minOccurs="0" maxOccurs="unbounded">
                <xsd:element ref="record"/>
            </xsd:sequence>
        </xsd:complexType>

        <xsd:complexType name="recordType" id="record.ct">
            <xsd:sequence minOccurs="0">        
                <xsd:element name="datafield" type="dataFieldType" minOccurs="0" maxOccurs="unbounded"/>
            </xsd:sequence>
            <xsd:attribute name="type" type="recordTypeType" use="optional"/>
            <xsd:assert test="count(./datafield[@tag = '100']) = 1"
                xerces:message="A record must only have up to one 1XX field"/>
        </xsd:complexType>
        <xsd:simpleType name="recordTypeType" id="type.st">
            <xsd:restriction base="xsd:NMTOKEN">
                <xsd:enumeration value="Bibliographic"/>
                <xsd:enumeration value="Authority"/>
                <xsd:enumeration value="Holdings"/>
                <xsd:enumeration value="Classification"/>
                <xsd:enumeration value="Community"/>
            </xsd:restriction>
        </xsd:simpleType>
        <xsd:complexType name="dataFieldType" id="datafield.ct">
            <xsd:attribute name="tag" type="tagDataType" use="required"/>
            <xsd:attribute name="ind1" type="indicatorDataType" use="required"/>
            <xsd:attribute name="ind2" type="indicatorDataType" use="required"/>

            <xsd:assert
                test="not((@tag = '100' or @tag = '110' or @tag = '111' or @tag = '130') and not(@ind2 = ' '))"
                xerces:message="1XX fields must have a blank 2nd indicator">
                <xsd:annotation>
                    <xsd:documentation xml:lang="en">This assertation ensures that the second indicator
                        of a 1XX field is blank.</xsd:documentation>
                </xsd:annotation>
            </xsd:assert>
        </xsd:complexType>
        <xsd:simpleType name="tagDataType" id="tag.st">
            <xsd:restriction base="xsd:string">
                <xsd:whiteSpace value="preserve"/>
                <xsd:pattern
                    value="010|020|040|042|050|082|100|110|111|130|245|246|250|260|264|300|336|337|338|500|505|520|490|600|610|611|630|650|655|700|710|711|730|830|856"
                />
            </xsd:restriction>
        </xsd:simpleType>
        <xsd:simpleType name="indicatorDataType" id="ind.st">
            <xsd:restriction base="xsd:string">
                <xsd:whiteSpace value="preserve"/>
                <xsd:pattern value="[\da-z ]{1}"/>
            </xsd:restriction>
        </xsd:simpleType>
    </xsd:schema>

这是我的XML数据:

<collection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.loc.gov/MARC21/slim file:/Users/NetanelGanin/Desktop/Test.xsd"
    xmlns="http://www.loc.gov/MARC21/slim">

    <record type="Bibliographic">
        <datafield tag="010" ind1=" " ind2=" "/>
        <datafield tag="020" ind1=" " ind2=" "/>
        <datafield tag="040" ind1=" " ind2=" "/>
        <datafield tag="042" ind1=" " ind2=" "/>
        <datafield tag="050" ind1="0" ind2="0"/>
        <datafield tag="082" ind1="0" ind2="0"/>
        <datafield tag="100" ind1="1" ind2=" "/>
        <datafield tag="245" ind1="1" ind2="0"/>
    </record>
</collection>

第二个断言工作正常! (每当我通过使@ind2不是空格来测试它时),但第一个断言只是一直失败。我甚至试过写作:

 <xsd:assert test="./datafield"/>

只是说,“嘿,如果有一个名为datafield的子元素,那么传递断言,”它就失败了!

思想?

1 个答案:

答案 0 :(得分:3)

这是一个名称空间问题,已在以下XSD中修复。

此外,假设断言消息正确表示您的意图,第一个断言条件应为&lt;= 1。另请注意,./是多余的,可以简化。

这是正确的第一个断言:

    <xsd:assert test="count(slim:datafield[@tag = '100']) &lt;= 1"
                xerces:message="A record must only have up to one 1XX field"/>

以下是完整,正确的XSD:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://www.loc.gov/MARC21/slim" 
            xmlns:slim="http://www.loc.gov/MARC21/slim"
            xmlns:xerces="http://xerces.apache.org"
            elementFormDefault="qualified" attributeFormDefault="unqualified"  
            xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
            vc:minVersion="1.1">

  <xsd:element name="record" type="slim:recordType" 
    nillable="true" id="record.e"/>
  <xsd:element name="collection" type="slim:collectionType" 
    nillable="true" id="collection.e"/>
  <xsd:complexType name="collectionType" id="collection.ct">
    <xsd:sequence minOccurs="0" maxOccurs="unbounded">
      <xsd:element ref="slim:record"/>
    </xsd:sequence>
  </xsd:complexType>
  <xsd:complexType name="recordType" id="record.ct">
    <xsd:sequence minOccurs="0">        
      <xsd:element name="datafield" type="slim:dataFieldType" 
        minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
    <xsd:attribute name="type" type="slim:recordTypeType" 
      use="optional"/>
    <xsd:assert test="count(slim:datafield[@tag = '100']) &lt;= 1"
                xerces:message="A record must only have up to one 1XX field"/>
  </xsd:complexType>
  <xsd:simpleType name="recordTypeType" id="type.st">
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="Bibliographic"/>
      <xsd:enumeration value="Authority"/>
      <xsd:enumeration value="Holdings"/>
      <xsd:enumeration value="Classification"/>
      <xsd:enumeration value="Community"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:complexType name="dataFieldType" id="datafield.ct">
    <xsd:attribute name="tag" type="slim:tagDataType" use="required"/>
    <xsd:attribute name="ind1" type="slim:indicatorDataType" use="required"/>
    <xsd:attribute name="ind2" type="slim:indicatorDataType" use="required"/>
    <xsd:assert
      test="not((@tag = '100' or @tag = '110' 
                 or @tag = '111' or @tag = '130') and not(@ind2 = ' '))"
      xerces:message="1XX fields must have a blank 2nd indicator">
      <xsd:annotation>
        <xsd:documentation xml:lang="en">
          This assertation ensures that the second indicator
          of a 1XX field is blank.
        </xsd:documentation>
      </xsd:annotation>
    </xsd:assert>
  </xsd:complexType>
  <xsd:simpleType name="tagDataType" id="tag.st">
    <xsd:restriction base="xsd:string">
      <xsd:whiteSpace value="preserve"/>
      <xsd:pattern
        value="010|020|040|042|050|082|100|110|111|130|245|246|
               250|260|264|300|336|337|338|500|505|520|490|600|
               610|611|630|650|655|700|710|711|730|830|856"/>
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="indicatorDataType" id="ind.st">
    <xsd:restriction base="xsd:string">
      <xsd:whiteSpace value="preserve"/>
      <xsd:pattern value="[\da-z ]{1}"/>
    </xsd:restriction>
  </xsd:simpleType>  
</xsd:schema>
相关问题