2016-11-18 102 views
1

我尽我所能用XSD 1.1模式验证XML文档,但没有办法。我已经简化我的样本,看起来像这样:循环XSD 1.1声明

<?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实现的东西:断言是quantitytotal必须等于“行附件”的数量的总和。我看到很多使用“每个”关键字的样本,但从来没有效果。这里有一个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的理由:断言循环中的所有行。

感谢;)

回答

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> 
+0

非常感谢kjhughes;)就像一个魅力。 – Fxbrandon

0

你的深度嵌套使得它很难看到这里的逻辑,但如果我没有看错你的xs:断言是牙列的定义的一部分,而行元素不有一个叫做行的孩子,因此行/附件/附件将不会选择任何内容。

顺便说一句,你的“所以你可以看到”是令人难以置信的挑衅。你真的希望我们通过阅读未能实现它的代码来看到你想要达到的目标吗?

+0

感谢迈克尔,我会回答自己有一个更好的解释。 – Fxbrandon