【问题标题】:Can I explicitly set the value of an attribute obtained from a type assigned to an element in XSD我可以显式设置从分配给 XSD 中元素的类型获得的属性的值吗
【发布时间】:2013-10-29 18:16:39
【问题描述】:

假设我有以下复杂类型

<xs:complexType name="matrix">
    <xs:simpleContent>
        <xs:extension base="xs:string">
            <xs:attribute name="rows" type="xs:integer" use="required" />
            <xs:attribute name="cols" type="xs:integer" use="required" />
        </xs:extension>
    </xs:simpleContent>
</xs:complexType>

这代表一个矩阵,我的想法是我可以像这样填充它(例如,对于 2x2 矩阵):

<matrix rows=2 cols=2>1,2,3,4</matrix>

现在说我想根据这种类型制作一个元素,比如

<xs:element name="eulerangles" type="matrix">

在这种情况下,我仍然需要显式设置 rows 和 cols 属性,但该元素将始终具有 3 行和 3 列。是否有可能以某种方式将属性设置为模式中的特定数字,这样我就不需要明确指定我想要 3 行和 3 列

即而不必写这个:

<eulerangles rows=3 cols=3>1,2,3,4,5,6,7,8,9</eulerangles>

我希望能够这样写

<eulerangles>1,2,3,4,5,6,7,8,9</eulerangles>

虽然 eulerangles 仍然是具有 3 行和 3 列的“矩阵”类型

注意:我对 XML 和 XSD 非常陌生。我非常感谢任何有助于改善我的风格的 cmet。

【问题讨论】:

    标签: xml xsd


    【解决方案1】:

    您可能在 XSD 1.0 中获得的最接近的模型是这样的:

    <?xml version="1.0" encoding="utf-8" ?>
    <!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
    <xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" xmlns="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <xs:complexType name="matrixbase">
            <xs:simpleContent>
                <xs:extension base="xs:string">
                    <xs:attribute name="rows" type="xs:integer"/>
                    <xs:attribute name="cols" type="xs:integer"/>
                </xs:extension>
            </xs:simpleContent>
        </xs:complexType>
    
        <xs:complexType name="matrix">
            <xs:simpleContent>
                <xs:restriction base="matrixbase">
                    <xs:attribute name="rows" type="xs:integer" use="required"/>
                    <xs:attribute name="cols" type="xs:integer" use="required"/>
                </xs:restriction>
            </xs:simpleContent>
        </xs:complexType>
    
    
        <xs:complexType name="eulerangles">
            <xs:simpleContent>
                <xs:restriction base="matrixbase">
                    <xs:attribute name="rows" type="xs:integer" use="prohibited"/>
                    <xs:attribute name="cols" type="xs:integer" use="prohibited"/>
                </xs:restriction>
            </xs:simpleContent>
        </xs:complexType>
    </xs:schema>
    

    一旦声明了必需的属性,就无法让它们在子类型中“消失”。解决方案可能是重新定义层次结构(matrixbase),使基类型声明属性可选;然后根据其他已建立的规则将它们设为强制(矩阵)或禁止(欧拉角、四元数等)。

    【讨论】:

    • 在您的示例中,如果禁止行和列,这是否意味着它们实际上并未设置为 3(或任何值),并且它们不再是 eulerangles 类型的一部分?
    • @9a3eedi,是的,这意味着它们不适用,因此不设置为 PSVI 的一部分。我认为你的观点是针对众所周知的矩阵(我通过提到四元数来加强这一点),提供行和列是没有意义的,因为它是多余的 - 这些矩阵的特征是先验建立的。我的经验告诉我要避免在 XSD 中使用默认值和固定值,因为它最终会促进暗示 PSVI 的实现,这实际上是非常有限的。我也不相信那些说它是一个很好的文档机制的人(我更喜欢注释)。
    【解决方案2】:

    我认为你应该能够做到这一点:

    <xs:complexType name="eulerangles">
        <xs:simpleContent>
            <xs:restriction base="matrix">
                <xs:attribute name="rows" type="xs:integer" fixed="3"/>
                <xs:attribute name="cols" type="xs:integer" fixed="3"/>
            </xs:restriction>
        </xs:simpleContent>
    </xs:complexType>
    

    在 XSD 1.1 中,您可以添加断言

    <xs:assert test="count(tokenize($value, ',')) = @rows * @cols"/>
    

    【讨论】:

    • matrix 必须将属性“放松”从必需到可选(否则您提供的限制无效);就 XSD 而言,具有固定值将起作用;尽管它允许有效的 XML 看起来仍然很笨拙(只提供rowscols 之一)。有趣的事情(至少对我来说)直到你的帖子我才意识到,具有固定值的 use="prohibited" 是有效的(规范似乎没有暗示其他情况,.NET 和 Xerces)但是这个组合似乎没用,因为不能以任何方式使用固定值(例如填充 PSVI)。
    • 为什么需要放宽到可选?如果这些值是固定的,则仍然保证会提供这些值,因此您会认为它会满足“必需”的要求。
    • 好吧,我刚刚在验证器上测试了代码,确实你是对的。我不得不将矩阵放宽为可选,我可能会考虑这样做。但是,我不明白你说的没用是什么意思。如果我必须使用典型库解析通过此架构验证的 XML,这是否意味着解析器无法将 eulerangle 元素识别为具有 3 行和 3 列的矩阵类型?
    • @9a3eedi,“无用”仅指允许固定属性应用于禁止的情况,相对于 PSVI。
    猜你喜欢
    • 1970-01-01
    • 2016-11-16
    • 1970-01-01
    • 2021-03-05
    • 2011-11-03
    • 2012-02-23
    • 2011-07-08
    • 1970-01-01
    • 2021-12-24
    相关资源
    最近更新 更多