2

我有一个 XSD 元素

<xsd:element name="author" type="cmd:Author" nillable="true">
    <xsd:annotation>
        <xsd:documentation>Contains author name and author id
        </xsd:documentation>
    </xsd:annotation>
</xsd:element>

类型作者:

<xsd:complexType name="Author">
    <xsd:annotation>
        <xsd:documentation>Author's name and id.
        </xsd:documentation>
    </xsd:annotation>
    <xsd:simpleContent>
        <xsd:extension base="cmd:AuthorName">
             <xsd:attribute name="id" type="cmd:Id" use="optional">
                <xsd:annotation>
                    <xsd:documentation>Author's Id
                    </xsd:documentation>
                </xsd:annotation>
            </xsd:attribute>
        </xsd:extension>
    </xsd:simpleContent>
</xsd:complexType>

基地作者姓名:

<xsd:simpleType name="AuthorName">
    <xsd:annotation>
        <xsd:documentation>Type defining author's name. 
                It may contain characters from AllowedChars
        </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="cmd:AllowedChars">
        <xsd:maxLength value="112"/>
    </xsd:restriction>
</xsd:simpleType>

类型标识:

<xsd:simpleType name="Id">
    <xsd:annotation>
        <xsd:documentation>Id
        </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:string">
        <xsd:pattern value="\d{6}"/>
    </xsd:restriction>
</xsd:simpleType>

问题是我总是有一个 ID,但有时 AuthorName 可能为空。

在那种情况下,我得到的是:

<author id="111111"/>

我想要得到的是:

<author id="111111" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:nil="true"/>

我的实际状态使架构兼容性出现问题。是否可以在不更改 XSD 模型的情况下做我想做的事情?将 Author 拆分为 AuthorName 和 AuthorId 不向后兼容,并且需要重写相当大的应用程序。

附加信息(我不太确定什么有用,什么没用):应用程序在 J2E 中,我正在将 xsd 与 JAXB 绑定,并且正在使用 XJC 生成类。

生成类作者:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Author", propOrder = {
    "value"
})
public class Author implements Serializable
{
    @XmlValue
    protected String value;
    @XmlAttribute(name = "id")
    protected String id;
    //getters and setters
}
4

1 回答 1

1

您可能还需要提供有关实施的更多信息;最有可能的是,这限制了您获得所需的东西。

规格明智,你是对的。XSD 规范明确指出其他 XML 属性可能出现在 xsi:nil 属性已设置为 true 的元素中(重点是我的)。

xsi:nil如果一个元素具有值为的属性,则它可能是无内容的true。如此标记的元素必须为空,但如果相应的复杂类型允许,则可以携带属性。

问题是大多数绑定技术都没有实现这种行为。例如, MSDN 上的这篇文章清楚地表明您的方案不受其标准 XML 序列化程序的支持。这是一个摘录:

  • 将 XML 文档反序列化为对象时:如果XmlSerializer类遇到指定 xsi:nil="true" 的 XML 元素,它将为相应对象分配空引用并忽略任何其他属性。如果 XML 文档是由允许其他属性与 xsi:nil="true" 一起出现的 XML 模式实现创建的,则可能会出现这种情况——实际上没有将nil值 true 绑定到空对象引用。

相反,它不能以相反的方式工作,即如果设置了任何其他属性,它将无法序列化 xsi:nil="true" 属性。

如果您在内部执行此操作,则可能有一些方法可以调整序列化程序以按照您想要的方式工作 - 再次,您需要提供更多信息。否则,您应该假设,正如我上面所展示的,有些平台根本无法正常工作(开箱即用)。

于 2015-12-05T00:08:44.940 回答