1

我想解耦两个共享一组 XML 类型的开发团队的关注点。共享类型在共享 XSD 中定义。但是,第二个团队需要在共享 XML 类型中的大多数字段上添加一组额外的属性,这些属性只与他们的一组需求相关。目前,这些专有属性嵌入在共享 XSD 的大部分字段中。

我想将这些属性隔离为一组扩展共享 XML 类型的 XML 类型,就像您在简单的 OO 语言中所做的那样。Ayesha Malik 有一些想法让我开始使用在面向对象框架中构建 XML 模式的技术

感谢添加属性...添加方面,我能够将属性添加到各个字段的 complexTypes。但是,当我尝试覆盖其中一种复杂的共享类型中的子元素的类型时,Eclipse 中的验证会抱怨说

粒子类型不是对基础粒子的有效限制。

如果我将各个子元素类型保持不变,则验证效果很好。但是如果我将它们的类型更改为新的派生类型,验证将失败。这是令人沮丧的,因为各个子元素的类型与父类型不同的事实是练习的重点。我想为父类型中的每个字段/子元素添加一组属性,但我没有看到任何方法。

我隔离了一个示例,该示例演示了您可以使用 simpleContent 将属性添加到 simpleType 和 complextType。但我无法使用 complextContent 将属性添加到派生的 complexType。例如,在下面的 complexType“SearchPamphlet”中,我尝试同时使用 <xs:extension> 和 <xs:restriction>。我还尝试将“基础”设置为“书”和“小册子”。所有这些方法都会产生相同的错误。有没有人有什么建议?

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="qualified" attributeFormDefault="unqualified">

    <xs:complexType name="Book">
        <xs:sequence>
            <xs:element name="Title" type="xs:string" />
            <xs:element name="Author" type="xs:string" />
            <xs:element name="ISBN" type="xs:string" />
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="Pamphlet">
        <xs:complexContent>
            <xs:restriction base="Book">
                <xs:sequence>
                    <xs:element name="Title" type="xs:string" />
                    <xs:element name="Author" type="xs:string" />
                    <xs:element name="ISBN" type="PamphletISBN" />
                </xs:sequence>
            </xs:restriction>
        </xs:complexContent>
    </xs:complexType>

    <xs:simpleType name="ISBNType">
        <xs:restriction base="xs:string" />
    </xs:simpleType>

    <xs:simpleType name="PamphletISBN">
        <xs:restriction base="ISBNType">
            <xs:maxLength value="5" />
        </xs:restriction>
    </xs:simpleType>

    <xs:complexType name="SearchablePamphlet">
        <xs:complexContent>
            <xs:restriction base="Book">
                <xs:sequence>
                    <xs:element name="Title" type="SearchableString" />
                    <xs:element name="Author" type="SearchableString" />
                    <xs:element name="ISBN" type="SearchablePamphletISBN" />
                </xs:sequence>
            </xs:restriction>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="SearchablePamphletISBN">
        <xs:simpleContent>
            <xs:extension base="PamphletISBN">
            <xs:attributeGroup ref="searchableAttributes" />
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>

    <xs:complexType name="SearchableString">
        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:attributeGroup ref="searchableAttributes" />
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>

    <xs:attributeGroup name="searchableAttributes">
        <xs:attribute name="caseMatches" type="xs:boolean" />
        <xs:attribute name="spellingMatches" type="xs:boolean" />
        <xs:attribute name="checksum" type="xs:integer" />
    </xs:attributeGroup>

</xs:schema>
4

3 回答 3

0

我找到了一个解决方案,可以隔离我所关注的问题。解决方案是使用“ Salami Slice ”设计模式,结合替代组的。

对于无所不知且有先见之明的分析师,基本文件可能会预测非常发展的需求,或者如果您公司的标准委员会可以在公司的开发小组每次提出另一个时更改基本类型的 XSD 文件他们想要添加的元素或属性。但在我职业生涯的工作经历中,我从未有机会与这样的个人或标准委员会一起工作。

我已经发布了三个 XSD 文件,它们在下面展示了关注点的隔离,以及一个示例 XML 文件。在发布的代码中,我假设 BaseTypes.xsd 文件被冻结并处于变更审查委员会的控制之下。我还假设 DerivedTypes.xsd、Products.xsd 和 Test.xml 文件将由本地产品开发组生成:

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- XMLInheritance_BaseDataTypes -->

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
      targetNamespace="http://www.company.org/XMLInheritance" xmlns:bk="http://www.company.org/XMLInheritance"
      elementFormDefault="qualified" attributeFormDefault="unqualified">

      <xs:element name="Book" type="bk:BookType" />
      <xs:element name="Title" type="xs:string" />
      <xs:element name="Author" type="xs:string" />
      <xs:element name="ISBN" type="bk:ISBNType" />

      <xs:simpleType name="ISBNType">
        <xs:restriction base="xs:string" />
      </xs:simpleType>

      <xs:complexType name="BookType">
        <xs:sequence>
          <xs:element ref="bk:Title" />
          <xs:element ref="bk:Author" />
          <xs:element ref="bk:ISBN" />
        </xs:sequence>
      </xs:complexType>

    </xs:schema>


    ----------

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- XMLInheritance_DerivedDataTypes -->

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
      targetNamespace="http://www.company.org/XMLInheritance" xmlns:bk="http://www.company.org/XMLInheritance"
      elementFormDefault="qualified" attributeFormDefault="unqualified">

      <xs:include schemaLocation="XMLInheritance_BaseDataTypes.xsd" />

      <xs:element name="SearchableBook" type="bk:SearchableBookType"
        substitutionGroup="bk:Book" />
      <xs:element name=" SearchableTitle " type="bk:SearchableString"
        substitutionGroup="bk:Title" />
      <xs:element name="SearchableAuthor" type="bk:SearchableString"
        substitutionGroup="bk:Author" />
      <xs:element name="SearchableISBN" type="bk:SearchableISBNType"
        substitutionGroup="bk:ISBN" />

      <xs:attributeGroup name="searchableAttributes">
        <xs:attribute name="caseMatches" type="xs:boolean" />
        <xs:attribute name="spellingMatches" type="xs:boolean" />
        <xs:attribute name="checksum" type="xs:integer" />
      </xs:attributeGroup>

      <xs:complexType name="SearchableBookType">
        <xs:complexContent>
          <xs:restriction base="bk:BookType">
            <xs:sequence>
              <xs:element ref="bk:SearchableTitle" />
              <xs:element ref="bk:SearchableAuthor" />
              <xs:element ref="bk:SearchableISBN" />
            </xs:sequence>
          </xs:restriction>
        </xs:complexContent>
      </xs:complexType>

      <xs:complexType name="SearchableISBNType">
        <xs:simpleContent>
          <xs:extension base="bk:ISBNType">
            <xs:attributeGroup ref="bk:searchableAttributes" />
          </xs:extension>
        </xs:simpleContent>
      </xs:complexType>

      <xs:complexType name="SearchableString">
        <xs:simpleContent>
          <xs:extension base="xs:string">
            <xs:attributeGroup ref="bk:searchableAttributes" />
          </xs:extension>
        </xs:simpleContent>
      </xs:complexType>

    </xs:schema>


    ----------
    <?xml version="1.0" encoding="UTF-8"?>
    <!-- XMLInheritance_DerivedProducts.xsd -->

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
      targetNamespace="http://www.company.org/XMLInheritance" xmlns:bk="http://www.company.org/XMLInheritance"
      elementFormDefault="qualified">
      <xs:include schemaLocation="XMLInheritance_DataTypes.xsd" />

      <xs:element name="Product">
        <xs:complexType>
          <xs:sequence>

            <xs:element name="Books">
              <xs:complexType>
                <xs:sequence maxOccurs="unbounded">
                  <xs:element name="Book" type="bk:BookType" />
                </xs:sequence>
              </xs:complexType>
            </xs:element>

            <xs:element name="SearchableBooks" minOccurs="0">
              <xs:complexType>
                <xs:sequence maxOccurs="unbounded">
                  <xs:element name="SearchableBook" type="bk:SearchableBookType" />
                </xs:sequence>
              </xs:complexType>
            </xs:element>
          </xs:sequence>
        </xs:complexType>
      </xs:element>

    </xs:schema>


    ----------
    <?xml version="1.0" encoding="UTF-8"?>
    <!-- XMLInheritance_Test.xml -->
    <bk:Product xmlns:bk="http://www.company.org/XMLInheritance"
      xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
      xs:schemaLocation="http://www.company.org/XMLInheritance XMLInheritance_DerivedProducts.xsd ">

      <bk:Books>
        <bk:Book>
          <bk:Title>Title</bk:Title>
          <bk:Author>Author</bk:Author>
          <bk:ISBN>ISBN</bk:ISBN>
        </bk:Book>
      </bk:Books>
      <bk:SearchableBooks>
        <bk:SearchableBook>
          <bk:SearchableTitle>Searchable Title</bk:SearchableTitle>
          <bk:SearchableAuthor>Searchable Author</bk:SearchableAuthor>
          <bk:SearchableISBN>Searchable ISBN</bk:SearchableISBN>
        </bk:SearchableBook>
      </bk:SearchableBooks>

    </bk:Product>
于 2012-08-02T13:14:01.860 回答
0

下面的 XSD 与您发布的源的意图严格匹配。主要目的是让您了解 XSD 中的限制是如何工作的,以及在创作中需要考虑的开销。

解释一下:您需要从“SearcheableBook”开始,而不是已经受到限制的 Book,这是一个拥有所有您需要的实体,然后您可以通过各种限制进行缩减。

<?xml version="1.0" encoding="UTF-8"?>
<!--XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com)-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:complexType name="SearchableBook" abstract="true">
        <xs:sequence>
            <xs:element name="Title" type="SearchableString"/>
            <xs:element name="Author" type="SearchableString"/>
            <xs:element name="ISBN" type="SearchableString"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="Book">
        <xs:complexContent>
            <xs:restriction base="SearchableBook">
                <xs:sequence>
                    <xs:element name="Title" type="SimpleTitle"/>
                    <xs:element name="Author" type="SimpleAuthor"/>
                    <xs:element name="ISBN" type="SimpleISBN"/>
                </xs:sequence>
            </xs:restriction>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="SimpleTitle">
        <xs:simpleContent>
            <xs:restriction base="SearchableString">
                <xs:attribute name="caseMatches" type="xs:boolean" use="prohibited"/>
                <xs:attribute name="spellingMatches" type="xs:boolean" use="prohibited"/>
                <xs:attribute name="checksum" type="xs:integer" use="prohibited"/>              
            </xs:restriction>
        </xs:simpleContent>     
    </xs:complexType>

    <xs:complexType name="SimpleAuthor">
        <xs:simpleContent>
            <xs:restriction base="SearchableString">
                <xs:attribute name="caseMatches" type="xs:boolean" use="prohibited"/>
                <xs:attribute name="spellingMatches" type="xs:boolean" use="prohibited"/>
                <xs:attribute name="checksum" type="xs:integer" use="prohibited"/>                              
            </xs:restriction>
        </xs:simpleContent>
    </xs:complexType>

    <xs:complexType name="SimpleISBN">
        <xs:simpleContent>
            <xs:restriction base="SearchableString">
                <xs:attribute name="caseMatches" type="xs:boolean" use="prohibited"/>
                <xs:attribute name="spellingMatches" type="xs:boolean" use="prohibited"/>
                <xs:attribute name="checksum" type="xs:integer" use="prohibited"/>                              
            </xs:restriction>
        </xs:simpleContent>
    </xs:complexType>

    <xs:complexType name="Pamphlet">
        <xs:complexContent>
            <xs:restriction base="SearchableBook">
                <xs:sequence>
                    <xs:element name="Title" type="SimpleTitle"/>
                    <xs:element name="Author" type="SimpleAuthor"/>
                    <xs:element name="ISBN" type="PamphletISBN"/>
                </xs:sequence>
            </xs:restriction>
        </xs:complexContent>
    </xs:complexType>
    <xs:complexType name="PamphletISBN">
        <xs:simpleContent>
            <xs:restriction base="SearchableString">
                <xs:maxLength value="5"/>
                <xs:attribute name="caseMatches" type="xs:boolean" use="prohibited"/>
                <xs:attribute name="spellingMatches" type="xs:boolean" use="prohibited"/>
                <xs:attribute name="checksum" type="xs:integer" use="prohibited"/>                              
            </xs:restriction>
        </xs:simpleContent>
    </xs:complexType>

    <xs:complexType name="SearchablePamphlet">
        <xs:complexContent>
            <xs:restriction base="SearchableBook">
                <xs:sequence>
                    <xs:element name="Title" type="SearchableString"/>
                    <xs:element name="Author" type="SearchableString"/>
                    <xs:element name="ISBN" type="SearchablePamphletISBN"/>
                </xs:sequence>
            </xs:restriction>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="SearchablePamphletISBN">
        <xs:simpleContent>
            <xs:restriction base="SearchableString">
                <xs:maxLength value="5"/>
            </xs:restriction>
        </xs:simpleContent>
    </xs:complexType>
    <xs:complexType name="SearchableString">
        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:attributeGroup ref="searchableAttributes"/>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>
    <xs:attributeGroup name="searchableAttributes">
        <xs:attribute name="caseMatches" type="xs:boolean"/>
        <xs:attribute name="spellingMatches" type="xs:boolean"/>
        <xs:attribute name="checksum" type="xs:integer"/>
    </xs:attributeGroup>
</xs:schema> 

另外,我会尝试以不同的方式思考模型,通过扩展,看看它是否可以以我称之为更清洁的方式完成(我最近看到一个复杂的限制案例如何扼杀市场上最昂贵的 XSD 编辑器。 ..)

于 2012-07-31T13:05:15.797 回答
0

感谢您的回复。它在语法上起作用。不幸的是,答案仅适用于只有一组派生类型的示例场景。这在多个开发团队使用共享类型的公共库工作的情况下无法扩展。

例如,在存在包含示例类型“ Book ”、“ Pamphlet ”和“ PamphletISBN ”的共享类型标准公司库的情况下,并且库 XSD 文件被标准进程“冻结”。

在这种情况下,搜索团队将无法修改Book类型,您也不会真的希望他们这样做。因为其他开发团队有相互竞争的需求。例如,销售团队想要为“ lifeTimeSales ”、“ topRanking ”、“ highestRatings ”等添加属性,而制作团队可能想要为“ monthlyPrinting ”、“ numberInInventory ”等添加属性。


从昨天开始,我就尝试使用elements来解决这个需求。不幸的是,这种方法也不能扩展到单一类型级别之外。

我要研究的另一种方法是使用替代组,看看这是否开辟了任何途径。如果我找到解决方案,我会发布它。

再次感谢您的建议。

于 2012-08-01T11:55:48.517 回答