Use datatype directly with in XML

让人想犯罪 __ 提交于 2019-12-24 15:25:47

问题


I'm trying to validate below XML with the below XSD:

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>

I'm facing 2 issues:

Unable to use xsd:unsignedInt directly in XML with below error

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

Unable to use both xsd:type and other non-namespaced attributes at the same time

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.

How do I edit my XSD to fix these issues. My final requirement is that all the Parameter nodes should contain Id and Flag attributes and its value should be validated against type provided (in the actual XML itself).

Using xsi:type inside xsd is not an option for me.


回答1:


Since xsi:type has to be derivable from the type specified in the XSD, and since Parameter is defined in the XSD to be complex, you'll probably want to create a child of Parameter, say Value, of xsd:anySimpleType that you can then override successfully via xsi:type in the XML document.

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>



回答2:


How do I edit my XSD to fix these issues.

Assuming it means without touching the XML, then there is no way to make it work with pure XSD, considering the meaning assigned to the xsi:type attribute. xsd:unsignedInt is a simple type, your element is complex type, simple content.

IF you're allowed to use only one of the built in XSD types, then the only way is to change your XML; one way is described in Kenneth's answer.

If you can use your own type, then something similar to this will work:

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

This sample then would work as expected:

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


来源:https://stackoverflow.com/questions/33917943/use-datatype-directly-with-in-xml

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!