LIST元素派生

时间:2017-01-05 06:59:12

标签: xml xsd

爬上XML学习曲线,我在使用list元素时出现了验证问题。我正在尝试创建一个list元素,该元素只允许特定key的值作为成员。

帮助您对后续内容进行建模的一些背景信息。我们有各种SOURCE个,每个NAME都有唯一的NAMEREFDESType格式受simpleType元素中的模式限制; NAMEsource_key唯一性由密钥source_key强制执行。

现在,尝试高效地使用此POWERSOURCE来提供相关数据字段的输入限制尚未产生预期的结果。 MODE是这些预期用法字段之一,是元素POWERSOURCE的子元素。目的是list能够SOURCE NAME REFDESType一个或多个POWERSOURCE但MSXML解析失败。 {好的,欢迎回到地板上大笑之后。}是的,这是针对没有第三方库的独立的基于EXCEL 2013的应用程序开发的。

对我来说似乎很明显的一个问题是NAME树从两个方向进入REFDESList。一旦通过keyref,再通过key。嗯...

解析错误: list'GEN-1 GEN-2 GEN-3 GEN-4'无法解析为<?xml version="1.0" encoding="UTF-8"?> <xs:schema targetNamespace="http://www.myCo.com" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ela="http://www.myCo.com" elementFormDefault="qualified"> <xs:element name="DB"> <xs:complexType> <xs:sequence> <xs:element ref="ela:SOURCE" maxOccurs="unbounded"/> <xs:element ref="ela:MODE" minOccurs="6" maxOccurs="13"/> </xs:sequence> </xs:complexType> <xs:key name="source_key"> <xs:selector xpath="ela:SOURCE"/> <xs:field xpath="ela:NAME"/> </xs:key> </xs:element> <xs:element name="SOURCE" type="ela:SOURCEType"/> <xs:element name="NAME" type="ela:REFDESType"/> <xs:element name="MODE" type="ela:MODEType"/> <xs:element name="POWERSOURCE" type="ela:REFDESList"> <xs:keyref name="powersource_ref" refer="ela:source_key"> <xs:selector xpath="."/> <xs:field xpath="."/> </xs:keyref> </xs:element> <xs:simpleType name="REFDESList"> <xs:list itemType="ela:REFDESType"/> </xs:simpleType> <xs:simpleType name="REFDESType"> <xs:restriction base="xs:string"> <xs:minLength value="2"/> <xs:maxLength value="9"/> <xs:pattern value="[A-Z]([A-Z0-9;&#32;&#45;]){1,8}"/> </xs:restriction> </xs:simpleType> <xs:complexType name="MODEType"> <xs:sequence> <xs:element ref="ela:POWERSOURCE"/> </xs:sequence> </xs:complexType> <xs:complexType name="SOURCEType" mixed="true"> <xs:sequence> <xs:element ref="ela:NAME"/> </xs:sequence> </xs:complexType> </xs:schema> 身份约束'{{{3} }} source_key”。

当然,使用<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <ela:DB xmlns:ela="http://www.myCo.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.myCo.com ELA.xsd"> <ela:SOURCE> <ela:NAME>GEN-1</ela:NAME> </ela:SOURCE> <ela:SOURCE> <ela:NAME>GEN-2</ela:NAME> </ela:SOURCE> <ela:SOURCE> <ela:NAME>GEN-3</ela:NAME> </ela:SOURCE> <ela:SOURCE> <ela:NAME>GEN-4</ela:NAME> </ela:SOURCE> <ela:MODE> <ela:POWERSOURCE>GEN-1 GEN-2 GEN-3 GEN-4</ela:POWERSOURCE> </ela:MODE> </ela:DB> 的效用对我来说很明显。现在,如果我只能理解这种方式是如何起作用的。替代方法也很受欢迎。

ELA.XSD:

KryptonLabel kryptonLabel = new KryptonLabel();
FontFamily fontFamily = new FontFamily("Arial");
Font font = new Font(fontFamily, 30, FontStyle.Regular, GraphicsUnit.Pixel);
kryptonLabel.StateCommon.ShortText.Font = font;

sample.xml中:

Font fontUpdatedSize = new Font(kryptonLabel.StateCommon.ShortText.Font.FontFamily,
                                        30,
                                        kryptonLabel.StateCommon.ShortText.Font.Style,
                                        GraphicsUnit.Pixel);
kryptonLabel.StateCommon.ShortText.Font = font;

3 个答案:

答案 0 :(得分:1)

您的keyref表示整个价值(即&#34; GEN-1 GEN-2 GEN-3 GEN-4&#34;)必须与某个键值匹配。

我认为没有任何方法可以使用keyref来实现与IDREFS类型相同的效果,其中列表中的每个项目必须单独满足完整性约束。您需要为此使用XSD 1.1断言。

答案 1 :(得分:1)

无法将各个列表成员与键匹配,只能匹配完整列表。在您的XML文件中,<ela:POWERSOURCE>的值是包含四个项目的列表。但是,没有<ela:NAME>来匹配该值(即具有相同四个项目的列表)。

架构的另一个问题是xs:keyref引用了祖先中定义的xs:key,这是不允许的。引用的键必须在同一元素声明中定义,或在元素的后代中定义。

使用key和keyref的现代解决方案

具有关键约束的可能解决方案是为每个列表项使用专用元素:

<ela:MODE>
    <ela:POWERSOURCE>
        <ela:NAME>GEN-1</ela:NAME>
        <ela:NAME>GEN-2</ela:NAME>
        <ela:NAME>GEN-3</ela:NAME>
        <ela:NAME>GEN-4</ela:NAME>
    </ela:POWERSOURCE>
</ela:MODE>

在架构中,您只需将REFDESList类型更改为:

即可
<xs:complexType name="REFDESList">
    <xs:sequence>
        <xs:element ref="ela:NAME" maxOccurs="unbounded"/>
    </xs:sequence>
</xs:complexType>

将keyref移动到与键相同的元素:

<xs:element name="DB">
    <xs:complexType>
        <xs:sequence>
            <xs:element ref="ela:SOURCE" maxOccurs="unbounded"/>
            <xs:element ref="ela:MODE" minOccurs="1" maxOccurs="13"/>
        </xs:sequence>
    </xs:complexType>
    <xs:key name="source_key">
        <xs:selector xpath="ela:SOURCE"/>
        <xs:field xpath="ela:NAME"/>
    </xs:key>
    <xs:keyref name="powersource_ref" refer="ela:source_key">
        <xs:selector xpath="ela:MODE/ela:POWERSOURCE/ela:NAME"/>
        <xs:field xpath="."/>
    </xs:keyref>
</xs:element>

具有ID和IDREFS的传统解决方案

@Michael Kay所述,有一种遗留机制 使用xs:IDxs:IDREFS种类型。 要将它们应用于您的架构,请删除xs:keyxs:keyref元素,并替换REFDESType的超类型:

<xs:simpleType name="REFDESType">
    <xs:restriction base="xs:ID"> <!-- Restrict legacy ID type -->
        <xs:minLength value="2"/>
        <xs:maxLength value="9"/>
        <xs:pattern value="[A-Z]([A-Z0-9;&#32;&#45;]){1,8}"/>
    </xs:restriction>
</xs:simpleType>

现在,<ela:NAME>元素的值是ID的子类型,可以通过IDREF或IDREFS类型的值引用:

<xs:element name="POWERSOURCE" type="xs:IDREFS"/> <!-- List of ID references -->

如果使用的工具符合标准,则调整后的XSD应验证您的XML文件。但请注意标准recommends that ID and IDREFS are only used for attributes,即

<ela:NAME id="GEN-1"/>
...
<ela:POWERSOURCE ref="GEN-1 GEN-2 GEN-3 GEN-4"/>

答案 2 :(得分:0)

@Michael Kay,@ Meyer;

除非我遗漏了某些内容(,结果证明我),但事实证明IDREFS建议毕竟不适用于MSXML(除非你处理掉simpleType中的list元素)。它在XMLSpy开发工具中工作正常,但是一旦模式试图通过SchemaCollection.Add方法加载到Excel 2013中,它就会抛出此错误。

  

列表数据类型必须派生自原子数据类型或联合   原子数据类型。

此错误消息似乎与报告的#39;相矛盾。 itemType的MSXML LIST元素定义是......

  

此处定义的内置数据类型或simpleType元素的名称   schema(或指定命名空间指示的另一个模式)。该   包含list元素的simpleType元素是从。派生的   列表值指定的简单类型。列表值必须是a   限定名称(QName)。使用simpleType元素子和   itemType属性是互斥的。

我相信我的架构符合LIST要求。 &#34; SOURCENAMEType&#34;是原始的simpleType,LIST simpleType&#34; IDREFListType&#34;是派生的。 原始XML:                                                     A-Z {1,8}&#34; /&GT;              

<xs:simpleType name="IDREFListType">
    <xs:list itemType="xs:IDREFS"/>
</xs:simpleType>

<xs:element name="SOURCELIST" type="ela:IDREFListType"/>

实际运行的修订版本:我将其重写为通用XML,以便可以轻松复制和重复使用。请注意,myLISTType不包含任何xs:list元素,即使它正是它的功能。原因是由于填充它的复数形式的原子元素,即xs:IDREFS,它已经是一个Collection元素。在MSXML中,他们显然不会声明列表元素(在这种情况下),因此他们的解析器不会将其解释为根据W3C不允许的列表列表。 (我的假设是基于广泛的测试。)麻烦的是,我没有发现任何地方记录这个小细微差别。 Augh !!!

    <xs:schema targetNamespace="http://www.myCo.com" xmlns:pfx="http://www.myCo.com" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <xs:element name="root">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="IDNAME" type="pfx:myIDNAMEType" maxOccurs="unbounded"/>
                <xs:element name="myLIST" type="pfx:myLISTType"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:simpleType name="myIDNAMEType">
        <xs:restriction base="xs:ID">
            <xs:pattern value="[A-Z]([A-Z0-9;&#32;&#45;]){1,8}"/>
            <!-- pattern for illustrative purposes only, not req'd -->
        </xs:restriction>
    </xs:simpleType>
    <xs:simpleType name="myLISTType">
        <xs:restriction base="xs:IDREFS">
            <xs:minLength value="1"/>
            <xs:maxLength value="4"/>
            <!-- min/max for illustrative purposes only, not req'd -->
            <!-- defines limits for # of members permitted in list -->
        </xs:restriction>
    </xs:simpleType>
</xs:schema>

XML:

<pfx:IDNAME>BOGUS-1</pfx:IDNAME>
<pfx:IDNAME>BOGUS-2</pfx:IDNAME>
<pfx:IDNAME>BOGUS-3</pfx:IDNAME>
<pfx:IDNAME>BOGUS-4</pfx:IDNAME>
<pfx:myLIST>BOGUS-1 BOGUS-2 BOGUS-3 BOGUS-4</pfx:myLIST>

验证检测到以下错误(基于所示的限制方面):

  • 超过列表成员的数量;见最小/最大限制方面
  • 列表成员未被视为合法成员,例如BOGUS-9不在 IDNAME设置