如何使用子元素或引用改进 XML 模式?

Posted

技术标签:

【中文标题】如何使用子元素或引用改进 XML 模式?【英文标题】:How to improve XML schema with sub-elements or references? 【发布时间】:2018-11-29 01:22:49 【问题描述】:

我有一个如下所示的 xml 架构,但我注意到维护起来会非常复杂。

我想通过以下方式之一改进当前架构,但我不确定它们是否是最佳/正确路线:

选项 1:movies 中使用movieDetails 的所有元素的引用。

选项 2:添加 movieDetails 作为 movies 的子元素(坦率地说,我正在努力实现)

哪条路线最好,什么是构建它的最佳方式?

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

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                    targetNamespace="http://xml.netbeans.org/schema/AmazingMovies"
                    xmlns:tns="http://xml.netbeans.org/schema/AmazingMovies"
                    elementFormDefault="qualified">

    <xsd:complexType name="movies">
        <xsd:sequence>
            <xsd:element name="Title" type="xsd:string"/>
            <xsd:element name="Director" type="xsd:string"></xsd:element>
            <xsd:element name="Year" type="xsd:int"/>
        </xsd:sequence>
    </xsd:complexType>

    <xsd:complexType name="movieDetails">
        <xsd:sequence>
            <xsd:element name="Actor" type="xsd:string"/>
            <xsd:element name="numberOfCast" type="xsd:int"></xsd:element>
            <xsd:element name="releaseDate" type="xsd:date"/>
        </xsd:sequence>
    </xsd:complexType>

    <xsd:element name="OnDisplay">
        <xsd:complexType>
            <xsd:sequence >
                <xsd:element name="collectionOfMovies" type="tns:movies" minOccurs="0" maxOccurs="unbounded"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>

</xsd:schema>

额外信息

OnDisplay 元素会将movies 的所有元素添加到列表中,以便在解组时使用它们。但是,我还想将movieDetails 添加到OnDisplay,因此,将它们作为引用、子元素或其他形式包含在movies 中会很方便。

尝试了以下方法,但 XML 验证失败

方法一

<xsd:element name="MoviesAndDetails">
    <xsd:complexType name="movies">
        <xsd:sequence>
            <xsd:element name="Title" type="xsd:string"/>
            <xsd:element name="Director" type="xsd:string"></xsd:element>
            <xsd:element name="Year" type="xsd:int"/>
        </xsd:sequence>
    </xsd:complexType>

    <xsd:complexType name="movieDetails">
        <xsd:sequence>
            <xsd:element name="Actor" type="xsd:string"/>
            <xsd:element name="numberOfCast" type="xsd:int">     </xsd:element>
            <xsd:element name="releaseDate" type="xsd:date"/>
        </xsd:sequence>
    </xsd:complexType>
</xsd:element>

方法二

<xsd:complexType name="MoviesAndDetails">
    <xsd:complexType name="movies">
        <xsd:sequence>
            <xsd:element name="Title" type="xsd:string"/>
            <xsd:element name="Director" type="xsd:string"></xsd:element>
            <xsd:element name="Year" type="xsd:int"/>
            <xsd:element ref="Actor"/>
            <xsd:element ref="numberOfCast"/>
            <xsd:element ref="releaseDate"/>
        </xsd:sequence>
    </xsd:complexType>

    <xsd:complexType name="movieDetails">
        <xsd:sequence>
            <xsd:element name="Actor" type="xsd:string"/>
            <xsd:element name="numberOfCast" type="xsd:int">     </xsd:element>
            <xsd:element name="releaseDate" type="xsd:date"/>
        </xsd:sequence>
    </xsd:complexType>
</xsd:element>

【问题讨论】:

【参考方案1】:

如果您想将movieDetails 元素作为collectionOfMovies 的子元素,那么您可以将tns:movieDetails 类型的movieDetails 元素添加到movies 元素的序列中。

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  targetNamespace="http://xml.netbeans.org/schema/AmazingMovies"
  xmlns:tns="http://xml.netbeans.org/schema/AmazingMovies"
  elementFormDefault="qualified">

  <xsd:complexType name="movies">
    <xsd:sequence>
        <xsd:element name="Title" type="xsd:string"/>
        <xsd:element name="Director" type="xsd:string"></xsd:element>
        <xsd:element name="Year" type="xsd:int"/>
        <xsd:element name="movieDetails" type="tns:movieDetails"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="movieDetails">
    <xsd:sequence>
        <xsd:element name="Actor" type="xsd:string"/>
        <xsd:element name="numberOfCast" type="xsd:int"></xsd:element>
        <xsd:element name="releaseDate" type="xsd:date"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:element name="OnDisplay">
    <xsd:complexType>
        <xsd:sequence >
            <xsd:element name="collectionOfMovies" type="tns:movies" minOccurs="0" maxOccurs="unbounded"/>
        </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

</xsd:schema>

【讨论】:

谢谢...这正是我所需要的。只是不知道如何添加另一个元素作为子元素。 如果可能的话,我想再收到您的意见...我能够创建一个 JAXB 绑定以解组 XML。我已经按如下方式创建了对象OnDisplays todaysShow = new Ondisplays(); List&lt;movies&gt; movies_today = todaysShow.getMovieCollection(); 尽管如此,我可以设置诸如TitleDirectorYear 之类的元素,但是,我认为我也可以通过这种方式设置movieDetails 的元素,但是它只显示setmovieDetails 而不是其中包含的元素。我怎样才能做到这一点?

以上是关于如何使用子元素或引用改进 XML 模式?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 SaxonJS 进行模式验证以获取缺失的引用

如何使用 jQuery 从子元素中获取数据以在 xml api 中查找其他子元素?

生成XML文档时如何插入元素计数

如何使用 Angular 4 从 Parent 获取子 DOM 元素引用

使用访问者模式时如何引用子结果?

如何找到 xml 对象的第 N 个元素