在XML中直接使用数据类型

时间:2015-11-25 13:37:45

标签: xml xsd xml-validation

我尝试使用以下XSD验证以下XML:

XML

<Device xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Parameter Id="100" Flag="100" xsi:type="xsd:unsignedInt">-100</Parameter>
</Device>

XSD

<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <xsd:element name="Device">
           <xsd:complexType>
                <xsd:sequence>
                   <xsd:element name='Parameter' type='paramType' minOccurs='0' maxOccurs='unbounded' />
                </xsd:sequence>        
           </xsd:complexType>
        </xsd:element>

        <xsd:complexType name="paramType">              
                        <xsd:attribute name="Id" use="required"/>
                        <xsd:attribute name="Flag" use="required"/>
                        <xsd:anyAttribute processContents="lax"/>            
        </xsd:complexType>

</xsd:schema>

我面临两个问题:

无法直接在XML中使用xsd:unsignedInt且错误

Type 'xsd:unsignedInt' is not validly derived from the type definition, 'paramType', of element 'Parameter'

无法同时使用xsd:type和其他非命名空间属性

Element 'Parameter' is a simple type, so it cannot have attributes, excepting those whose namespace name is identical to 'http://www.w3.org/2001/XMLSchema-instance' and whose [local name] is one of 'type', 'nil', 'schemaLocation' or 'noNamespaceSchemaLocation'. However, the attribute, 'Flag' was found.

如何编辑XSD以解决这些问题。我的最终要求是所有Parameter节点都应包含IdFlag属性,并且应根据提供的类型验证其值(在实际的XML本身中)。

在xsd中使用xsi:type对我来说不是一个选项。

2 个答案:

答案 0 :(得分:1)

由于xsi:type必须可以从XSD中指定的类型派生,并且由于Parameter在XSD中定义为复杂的,所以你可能想要创建一个参数的子节点,比如说Valuexsd:anySimpleType,然后您可以通过XML文档中的xsi:type成功覆盖。

XML

<?xml version="1.0" encoding="UTF-8"?>
<Device xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Parameter Id="100" Flag="100">
        <Value xsi:type="xsd:unsignedInt">100</Value>
    </Parameter>
</Device>

XSD

<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="Device">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name='Parameter' type='paramType' 
                     minOccurs='0' maxOccurs='unbounded' />
      </xsd:sequence>        
    </xsd:complexType>
  </xsd:element>

  <xsd:complexType name="paramType">              
    <xsd:sequence>
      <xsd:element name="Value" type="xsd:anySimpleType"/>
    </xsd:sequence>
    <xsd:attribute name="Id" use="required"/>
    <xsd:attribute name="Flag" use="required"/>
    <xsd:anyAttribute processContents="lax"/>
  </xsd:complexType>

</xsd:schema>

答案 1 :(得分:1)

  

如何编辑XSD以解决这些问题。

假设它意味着没有触及XML,那么考虑到分配给xsi:type属性的含义,就无法使其与纯XSD一起使用。 xsd:unsignedInt是一个简单类型,你的元素是复杂类型,内容简单。

如果您只允许使用其中一种内置XSD类型,那么唯一的方法就是更改XML; Kenneth的答案中描述了一种方式。

如果您可以使用自己的类型,那么类似的东西将起作用:

<?xml version="1.0" encoding="utf-8" ?>
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xtm="http://paschidev.com/schemas/metadata/xtm">
    <xsd:element name="Device">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="Parameter" minOccurs="0" maxOccurs="unbounded"/>
            </xsd:sequence>     
        </xsd:complexType>
    </xsd:element>

    <xsd:complexType name="FlaggedParameter">
        <xsd:simpleContent>
            <xsd:extension base="xsd:unsignedInt">
                <xsd:attribute name="Id" type="xsd:int" use="required"/>
                <xsd:attribute name="Flag" type="xsd:int" use="required"/>

            </xsd:extension>
        </xsd:simpleContent>
    </xsd:complexType>
</xsd:schema>

然后该样本将按预期工作:

<Device xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Parameter Id="100" Flag="100" xsi:type="FlaggedParameter">100</Parameter>
</Device>