【问题标题】:Looping XSD 1.1 assert循环 XSD 1.1 断言
【发布时间】:2016-11-18 12:09:01
【问题描述】:

我正在尽最大努力使用 XSD 1.1 模式验证 XML 文档,但没有办法。我已经简化了我的示例,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" elementFormDefault="qualified">
    <xs:element name="message1">
        <xs:complexType>
            <xs:sequence>
                <xs:element type="xs:string" name="indexmessage"/>
                <xs:element name="rows" maxOccurs="1">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="row" minOccurs="1" maxOccurs="unbounded">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element name="code">
                                            <xs:simpleType>
                                                <xs:restriction base="xs:string">
                                                    <xs:minLength value="1"/>
                                                    <xs:maxLength value="16"/>
                                                </xs:restriction>
                                            </xs:simpleType>
                                        </xs:element>
                                        <xs:element name="totalquantity">
                                            <xs:simpleType>
                                                <xs:restriction base="xs:decimal">
                                                    <xs:fractionDigits value="2"/>
                                                </xs:restriction>
                                            </xs:simpleType>
                                        </xs:element>
                                        <xs:element name="attachments" minOccurs="0" maxOccurs="1">
                                            <xs:complexType>
                                                <xs:sequence>
                                                    <xs:element name="attachment" minOccurs="1"
                                                  maxOccurs="unbounded">
                                                        <xs:complexType>
                                                            <xs:sequence>
                                                                <xs:element name="quantity">
                                                                    <xs:simpleType>
                                                                        <xs:restriction base="xs:decimal">
                                                                            <xs:fractionDigits value="2"/>
                                                                        </xs:restriction>
                                                                    </xs:simpleType>
                                                                </xs:element>
                                                            </xs:sequence>
                                                        </xs:complexType>
                                                    </xs:element>
                                                </xs:sequence>                                                                                              
                                            </xs:complexType>
                                        </xs:element>
                                    </xs:sequence>                                  
                                    <xs:assert test="every $r in row/attachments/attachment satisfies eq(row/quantitytotal, sum($r/quantity)"/>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

所以我想在 xs:assertion 中实现的是quantitytotal 必须等于“行附件”数量的总和。我见过许多使用“every”关键字的示例,但从未奏效。这里还有一个 XSD 示例:

<?xml version="1.0" encoding="UTF-8"?>
<message1>                  
    <indexmessage>02</indexmessage>     
    <rows>              
        <row>           
            <code>1789</code>       
            <totalquantity>3</totalquantity>
            <attachments>
                <attachment>
                    <quantity>2</quantity>
                </attachment>
                <attachment>
                    <quantity>1</quantity>
                </attachment>
            </attachments>
        </row>
        <row>
         ...
        </row>              
    </rows>             
</message1>

此示例中的断言必须为真,因为 2+1=3,这就是我尝试实现 xs:assert 循环所有行的原因。

非常感谢;)

【问题讨论】:

    标签: xml loops xsd assert


    【解决方案1】:

    您不需要“循环”通过row 元素。您的断言已经在row 级别;从那里,让sum() 添加所有quantity 值:

    <xs:assert test="sum(attachments/attachment/quantity) = totalquantity"/>
    

    将为每个row 自动检查此断言。

    这是您的 XSD 上下文中的上述断言:

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
               xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" 
               vc:minVersion="1.1" 
               elementFormDefault="qualified">
      <xs:element name="message1">
        <xs:complexType>
          <xs:sequence>
            <xs:element type="xs:string" name="indexmessage"/>
            <xs:element name="rows" maxOccurs="1">
              <xs:complexType>
                <xs:sequence>
                  <xs:element name="row" minOccurs="1" maxOccurs="unbounded">
                    <xs:complexType>
                      <xs:sequence>
                        <xs:element name="code">
                          <xs:simpleType>
                            <xs:restriction base="xs:string">
                              <xs:minLength value="1"/>
                              <xs:maxLength value="16"/>
                            </xs:restriction>
                          </xs:simpleType>
                        </xs:element>
                        <xs:element name="totalquantity">
                          <xs:simpleType>
                            <xs:restriction base="xs:decimal">
                              <xs:fractionDigits value="2"/>
                            </xs:restriction>
                          </xs:simpleType>
                        </xs:element>
                        <xs:element name="attachments" minOccurs="0" maxOccurs="1">
                          <xs:complexType>
                            <xs:sequence>
                              <xs:element name="attachment" minOccurs="1"
                                          maxOccurs="unbounded">
                                <xs:complexType>
                                  <xs:sequence>
                                    <xs:element name="quantity">
                                      <xs:simpleType>
                                        <xs:restriction base="xs:decimal">
                                          <xs:fractionDigits value="2"/>
                                        </xs:restriction>
                                      </xs:simpleType>
                                    </xs:element>
                                  </xs:sequence>
                                </xs:complexType>
                              </xs:element>
                            </xs:sequence>                                                                                              
                          </xs:complexType>
                        </xs:element>
                      </xs:sequence>                                  
                      <xs:assert test="sum(attachments/attachment/quantity) = totalquantity"/>
                    </xs:complexType>
                  </xs:element>
                </xs:sequence>
              </xs:complexType>
            </xs:element>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:schema>
    

    【讨论】:

      【解决方案2】:

      您的深层嵌套很难看到这里的逻辑,但是如果我没看错,您的 xs:assert 是元素行定义的一部分,并且行元素没有称为行的子元素,因此行/附件/附件不会选择任何内容。

      顺便说一句,你的“如你所见”是令人难以置信的自以为是。您真的希望我们通过阅读无法实现的代码来了解您想要实现的目标吗?

      【讨论】:

      • 谢谢迈克尔,我会用更好的解释来回答自己。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多