在nil xml元素上指定属性

时间:2014-12-18 20:25:16

标签: c# .net xml xsd xsd.exe

这是一个很长的...

我有一个xsd,它指定了一个可以有一个nillable元素的复杂类型,但该元素有一个必需的属性。这是一个简化的例子:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" >
    <xs:element name="Test">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="NillableElementTest" type="MyNillableElement" nillable="true" minOccurs="0" maxOccurs="1"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="MyNillableElement">
        <xs:sequence>
            <xs:element name="id" minOccurs="1" maxOccurs="unbounded"/>
        </xs:sequence>
        <xs:attribute name="RequredAttribute" use="required"/>
    </xs:complexType>
</xs:schema>

根据以上架构,以下xml文档有效:

<Test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <NillableElementTest RequredAttribute="test" xsi:nil="true"></NillableElementTest>
</Test>

<Test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
</Test>

如果NillableElementTest元素没有RequredAttribute值,则无效:

<Test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <NillableElementTest xsi:nil="true"></NillableElementTest>
</Test>

我有一个表示上述模式的对象模型(类)。对象模型是由.net框架工具从xsd生成的。

如果我将xml反序列化为对象实例,只要xml指定xsi:nil =&#34; true&#34;,NillableTestElement属性始终为null。通常这对我来说是有意义的,除了NillableTestElement属性不代表在xml中指定的RequredAttribute值这一事实。

xml schema primer表示nil机制仅适用于元素值,而不适用于属性值。 xsi:nil =&#34; true&#34;可能没有任何元素内容,但它仍然可以携带属性。

元素为nil但属性似乎无法由生成的对象模型表示的场景。

所以现在如果我接受对象实例并尝试将其序列化为xml,如果对模式进行验证,我将获得无效的xml,因为该对象将MyNillableElement序列化为:

<Test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <NillableElementTest xsi:nil="true"></NillableElementTest>
</Test>

...显然xsd声明NillableELementTest元素必须具有RequredAttribute属性。

这是问题

那么如何(或可能)指定该元素为null,还指定了对象中的属性值,以便正确序列化?

1 个答案:

答案 0 :(得分:0)

你在问题​​中说得最好:

  

元素为零但属性不是的情况   似乎能够由生成的对象模型表示。

在C#中,子元素NillableElementTest表示为对另一个对象的引用。如果元素为零值,则将其解释为空引用,如您所知,它可能不会携带其他属性的值。

在XML中,正如您所示,可能有一个nil- 但仍带有其他属性的元素。这种范式不能很好地传递给对象。

允许您的MyNillableElement包含0个或更多id个实例,而不是至少1个?通过这种方式,您可以自己拥有一个空的,可以携带其他属性,而不是null / nil。