如何使用具有约束的DOM针对XSD验证XML?

时间:2019-01-31 18:18:47

标签: xml dom xsd

晚安同事。

我使用DOM需要验证个XML针对XSD。 这是节略的示例XML和相应的XSD。 您会注意到XML是有效的,但是我需要强制执行另外两个约束:

  1. “LOT_MLT”<= “LOT_MIN”< “LOT_MAX”
  2. “LOT_MAX” 和 “LOT_MIN” 必须是 “LOT_MLT”
  3. 的精确倍数

有一种方法强制执行使用XSD和DOM这些限制? (我知道如何做到这一点没有这些两个额外的限制。)

谢谢您的帮助。

XML

  <?xml version="1.0" encoding="UTF-8" ?> 
  <Import>
    <Prd>
        <PRD_COD>SBBl</PRD_COD> 
        <PRD_DESC>Small Box, black</PRD_DESC> 
        <LOT_MLT>128</LOT_MLT> 
        <LOT_MIN>128</LOT_MIN> 
        <LOT_MAX>256</LOT_MAX> 
        <INV_INI>0</INV_INI> 
    </Prd>
    <Prd>
        <PRD_COD>LBWh</PRD_COD> 
        <PRD_DESC>Large Box, white</PRD_DES> 
        <LOT_MLT>32</LOT_MLT> 
        <LOT_MIN>64</LOT_MIN> 
        <LOT_MAX>640</LOT_MAX> 
        <INV_INI>64</INV_INI> 
    </Prd>
  </Import

XSD

<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="Import">
        <xs:complexType>
            <xs:sequence>    

                <xs:element name="Prd" minOccurs="2" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="PRD_COD" type="xs:normalizedString"/>
                            <xs:element name="PRD_DES" type="xs:normalizedString"/>
                            <xs:element name="LOT_MLT" type="xs:positiveInteger"/>                
                            <xs:element name="LOT_MIN" type="xs:positiveInteger"/>
                            <xs:element name="LOT_MAX" type="xs:positiveInteger"/>          
                            <xs:element name="INV_INI" type="xs:nonNegativeInteger"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>

            </xs:sequence>
        </xs:complexType>

        <xs:unique name="PRD_COD">
            <xs:selector xpath="Prd"/>
            <xs:field xpath="PRD_COD"/>
        </xs:unique>   

    </xs:element>
</xs:schema>

1 个答案:

答案 0 :(得分:0)

您可以使用XSD 1.1中可用的<xs:assert>指定所需的验证。这是对您的架构进行相应修改的完整内容:

<?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">

    <xs:element name="Import">
        <xs:complexType>
            <xs:sequence>    

                <xs:element name="Prd" minOccurs="2" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="PRD_COD" type="xs:normalizedString"/>
                            <xs:element name="PRD_DESC" type="xs:normalizedString"/>
                            <xs:element name="LOT_MLT" type="xs:positiveInteger"/>                
                            <xs:element name="LOT_MIN" type="xs:positiveInteger"/>
                            <xs:element name="LOT_MAX" type="xs:positiveInteger"/>          
                            <xs:element name="INV_INI" type="xs:nonNegativeInteger"/>
                        </xs:sequence>

                        <xs:assert test="LOT_MLT &lt;= LOT_MIN and LOT_MIN &lt; LOT_MAX and
                                         LOT_MIN mod LOT_MLT = 0 and LOT_MAX mod LOT_MLT = 0"/>

                    </xs:complexType>
                </xs:element>

            </xs:sequence>
        </xs:complexType>

        <xs:unique name="PRD_COD">
            <xs:selector xpath="Prd"/>
            <xs:field xpath="PRD_COD"/>
        </xs:unique>   

    </xs:element>
</xs:schema>

限制是通过test中的<xs:assert>属性指定的。该属性的值必须是XPath表达式,该表达式是根据上下文元素(在本例中为<Prd>)进行评估的。 XPath表达式是单个字符串。为了清楚起见,我将其分为两行。第一行用于测试约束条件(1),第二行用于约束条件(2)。

XML验证器应支持XSD 1.1。为了确保它可以识别XSD 1.1,在vc:minVersion头中添加了<xs:schema>属性。但是,这是可选的。

这是通过该架构通过验证的XML(使用XMLSpy):

<?xml version="1.0" encoding="UTF-8"?>
<Import xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="file:///C:/MySchemas/the_schema.xsd">
  <Prd>
      <PRD_COD>SBBl</PRD_COD>
      <PRD_DESC>Small Box, black</PRD_DESC>
      <LOT_MLT>128</LOT_MLT>
      <LOT_MIN>128</LOT_MIN>
      <LOT_MAX>256</LOT_MAX>
      <INV_INI>0</INV_INI>
  </Prd>
  <Prd>
      <PRD_COD>LBWh</PRD_COD>
      <PRD_DESC>Large Box, white</PRD_DESC>
      <LOT_MLT>32</LOT_MLT>
      <LOT_MIN>64</LOT_MIN>
      <LOT_MAX>640</LOT_MAX>
      <INV_INI>64</INV_INI>
  </Prd>
</Import>

XSD文件在其根元素中通过xsi:noNamespaceSchemaLocation属性链接到XML。这又是可选的,并取决于特定的验证器。

现在,您正在谈论DOM,您希望以某种方式使用它进行验证。 DOM不是一种工具,而是一种在内存中表示XML文档的方式,可以通过某些API进行访问。该表示仅在某些编程环境的上下文中才有意义(例如,从该XML提取数据或对其进行修改的Java)。您只需要一些了解XSD 1.1的XML验证程序,并且,如果您不想使用架构引用来修改XML,则必须有一种方法可以为其指定要验证的架构。

P.S。

对于那些使用XML模式和WSDL的人来说,以下链接可能很有趣:

如果您重视我对本网站的参与,请不要删除这些链接!