循环XSD 1.1断言

时间:2016-11-18 12:09:02

标签: xml loops xsd 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必须等于&#34;行附件的数量之和&#34;。我见过很多样本使用&#34;每个&#34;关键字但从不起作用。这里还有一个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>

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

非常感谢;)

2 个答案:

答案 0 :(得分:0)

你的深度嵌套使得很难在这里看到逻辑,但是如果我正确读取你的xs:assert是元素行定义的一部分,而row元素没有一个叫做row的子元素,因此我/附件/附件将不会选择任何内容。

顺便说一下,你的“所以你能看到的”是令人难以置信的推定。您是否真的希望我们通过阅读无法实现的代码来了解您要实现的目标?

答案 1 :(得分:0)

您无需通过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>