首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >列表元素推导

列表元素推导
EN

Stack Overflow用户
提问于 2017-01-05 06:59:11
回答 3查看 163关注 0票数 1

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

一个小小的背景来帮助你建立下面的模型。我们有各种各样的SOURCE,每个NAME都有唯一的NAMENAME格式受到simpleType元素中的模式的限制;REFDESTypeNAME唯一性由键source_key强制执行。

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

在我看来,有一个问题似乎很引人注目,那就是REFDESType树从两个方向进入POWERSOURCE。一次通过NAME,一次通过REFDESList。嗯..。

分析错误:keyref 'GEN-1 GEN-2 GEN-3 GEN-4‘不解析为身份约束'{http://www.myCo.com}source_key'.key

当然,对我来说,使用list的效用是显而易见的。现在,如果我能理解这种方式是如何不起作用的。替代办法也是受欢迎的。

ELA.XSD:

代码语言:javascript
复制
<?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>

sample.XML:

代码语言:javascript
复制
<?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>
EN

回答 3

Stack Overflow用户

发布于 2017-01-05 09:09:05

您的keyref表示,整个值(即"GEN-1 GEN-2 GEN-2 GEN-3 GEN-4")必须与一些关键值匹配。

我不认为keyref可以实现与IDREFS类型相同的效果,其中列表中的每个项都必须单独满足完整性约束。为此,您需要使用XSD1.1断言。

票数 1
EN

Stack Overflow用户

发布于 2017-01-05 09:10:53

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

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

带键和键的现代解决方案

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

代码语言:javascript
复制
<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类型更改为:

代码语言:javascript
复制
<xs:complexType name="REFDESList">
    <xs:sequence>
        <xs:element ref="ela:NAME" maxOccurs="unbounded"/>
    </xs:sequence>
</xs:complexType>

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

代码语言:javascript
复制
<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所提到的,有一种使用X:IDX:IDREFS类型的遗留机制。若要将它们应用于架构,请删除xs:keyxs:keyref元素,并替换REFDESType的超级类型。

代码语言:javascript
复制
<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类型的值引用:

代码语言:javascript
复制
<xs:element name="POWERSOURCE" type="xs:IDREFS"/> <!-- List of ID references -->

如果使用的工具符合标准,则调整后的XSD应该验证XML文件。但是请注意,标准建议ID和IDREFS仅用于属性。,即

代码语言:javascript
复制
<ela:NAME id="GEN-1"/>
...
<ela:POWERSOURCE ref="GEN-1 GEN-2 GEN-3 GEN-4"/>
票数 1
EN

Stack Overflow用户

发布于 2017-01-09 15:40:17

“迈克尔·凯,”迈耶;

除非我遗漏了一些东西(,原来我是),否则IDREFS建议毕竟不适用于MSXML (,除非您完全处理simpleType 中的list元素)。它在XMLSpy开发工具中运行良好,但是一旦模式试图通过SchemaCollection.Add方法加载到Excel2013中,就会引发此错误。

列表数据类型必须来自原子数据类型或原子数据类型的联合。

此错误消息似乎与用于列表的“报告”MSXML itemType元素定义相矛盾。

在此架构中定义的内置数据类型或simpleType元素的名称(或由指定的命名空间指示的另一个架构)。包含list元素的simpleType元素来自list值指定的简单类型。列表值必须是限定名(QName)。simpleType元素子元素和itemType属性的使用是相互排斥的。

我相信我的模式符合列表要求。"SOURCENAMEType“是派生LIST simpleType "IDREFListType”的原始simpleType。原始XML: A{1,8}“/>

代码语言:javascript
复制
<xs:simpleType name="IDREFListType">
    <xs:list itemType="xs:IDREFS"/>
</xs:simpleType>

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

实际工作的修订版:,我正在把它重写为泛型,这样就可以很容易地复制和重用它。请注意,myLISTType不包含任何xs:list元素,即使这正是它的工作方式。原因在于填充它的原子元素的复数形式,即xs:IDREFS,它已经是Collection元素。在MSXML中,他们显然会声明list元素(在这种情况下),这样他们的解析器就不会将其解释为列表列表,而根据W3C,这是不允许的。(我的假设是基于广泛的测试。)问题是,我在任何地方都没有发现这种细微差别。啊!

代码语言:javascript
复制
    <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:

代码语言:javascript
复制
<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>

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

  • 超过列表成员的数量;请参见min/max限制面
  • 不被承认为合法成员的名单成员,例如不属于IDNAME集的伪造-9成员
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41478986

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档