循环 XSD 1.1 断言

Looping XSD 1.1 assert

我正在尽最大努力使用 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必须等于"row attachments"的数量之和。我见过许多使用 "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 循环所有行的原因。

非常感谢 ;)

你的嵌套很深,很难看出这里的逻辑,但如果我没看错,你的 xs:assert 是元素行定义的一部分,并且行元素没有名为 row 的子元素, 因此 row/attachments/attachment 将 select 什么都没有。

顺便说一句,您的 "so as you can see" 非常自以为是。您真的希望我们通过阅读未能实现目标的代码来了解您想要实现的目标吗?

您不需要 "loop" 到 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>