【问题标题】:extracting element text value提取元素文本值
【发布时间】:2014-09-29 19:49:27
【问题描述】:

我正在使用JAXB 生成代码,以使用xsd 文件的原理图将xml 解组为java 实体。问题是生成的代码不会生成以下 xml 中指定的 organizationname

<organization>
    <name>Some organization's name goes here</name>
</organization>

这是Organization数据类型的xsd定义:

<xs:complexType name="Organization">
    <xs:sequence>
        <xs:element name="name" type="ON" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:attribute name="classCode" type="EntityClassOrganization" use="optional" fixed="ORG"/>
</xs:complexType>

这是xsd 数据类型的ON 定义:

<xs:complexType name="ON" mixed="true">
    <xs:annotation>
      <xs:documentation>
        A name for an organization. A sequence of name parts.
     </xs:documentation>
    </xs:annotation>
    <xs:sequence>
        <xs:element name="delimiter" type="en.delimiter"/>
        <xs:element name="prefix" type="en.prefix"/>
        <xs:element name="suffix" type="en.suffix"/>
    </xs:sequence>
    <xs:attribute name="use" use="optional" type="set_EntityNameUse">
      <xs:annotation>
        <xs:documentation>
            A set of codes advising a system or user which name
            in a set of like names to select for a given purpose.
            A name without specific use code might be a default
            name useful for any purpose, but a name with a specific
            use code would be preferred for that respective purpose.
        </xs:documentation>
      </xs:annotation>
    </xs:attribute>
</xs:complexType>

这是JAXB创建的java代码:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ON", propOrder = {"content"})
public class ON {

    @XmlElementRefs({
        @XmlElementRef(name = "delimiter", namespace = "urn:something", type = JAXBElement.class),
        @XmlElementRef(name = "prefix", namespace = "urn:something", type = JAXBElement.class),
        @XmlElementRef(name = "suffix", namespace = "urn:something", type = JAXBElement.class)
    })
    @XmlMixed
    protected List<Serializable> content;
    @XmlAttribute(name = "use")
    protected List<String> use;

    public List<Serializable> getContent() {
        if (content == null) {content = new ArrayList<Serializable>();}
        return this.content;
    }

    public List<String> getUse() {
        if (use == null) {use = new ArrayList<String>();}
        return this.use;
    }
}  

这个生成的 java 类有几个问题。首先,它创建List&lt;Serializable&gt; content;,而不是为delimiterprefixsuffix 创建单独的属性。同样重要的是,它也无法让我访问顶部 xml 中 name 标记内的文本值。当我从 xsd 文件中的 ON 定义中删除 mixed="true" 时,内容列表将替换为 delimiterprefixprefixsuffix 的单独属性,但我仍然无法获取文本name 元素的内容。我对删除 mixed=true 犹豫不决,因为我读到 mixed=true 指定 complextype 可以包含 elementsattributestext

除了为每个其他元素/属性生成单独的方法之外,我如何更改上面的代码以便生成检索name 元素文本的方法?

【问题讨论】:

    标签: java xml jaxb xsd


    【解决方案1】:

    试试我的Simplify plugin。我不确定它是否符合您的要求,但它是针对类似情况编写的。

    例子:

    <xs:complexType name="typeWithElementsProperty">
        <xs:choice maxOccurs="unbounded">
            <xs:element name="a" type="xs:string"/>
            <xs:element name="b" type="xs:int"/>
        </xs:choice>
    </xs:complexType>
    

    给你:

    @XmlElements({
        @XmlElement(name = "a", type = String.class)
        @XmlElement(name = "b", type = Integer.class),
    })
    protected List<Serializable> aOrB;
    

    但使用简化插件:

    <xs:complexType name="typeWithElementsProperty">
        <xs:choice maxOccurs="unbounded">
            <xs:annotation>
                <xs:appinfo>
                    <simplify:as-element-property/>
                </xs:appinfo>
            </xs:annotation>
            <xs:element name="a" type="xs:string"/>
            <xs:element name="b" type="xs:int"/>
        </xs:choice>
    </xs:complexType>
    

    你会得到:

    @XmlElement(name = "a", type = String.class)
    protected List<String> a;
    @XmlElement(name = "b", type = Integer.class)
    protected List<Integer> b;
    

    你有一个有点类似的情况,你得到你的财产是因为mixed="true"

    如果这对混合类型的 OOTB 不起作用,请将您的测试用例的 PR 发送给我here 并提交问题here

    更新

    我已经实现了this feature

    来自this

    <xs:complexType name="gh1" mixed="true">
        <xs:sequence>
            <xs:element name="a" type="xs:string">
                <xs:annotation>
                <xs:appinfo>
                    <simplify:as-element-property/>
                </xs:appinfo>
            </xs:annotation>
            </xs:element>
            <xs:element name="b" type="xs:int"/>
        </xs:sequence> 
    </xs:complexType>
    

    你会得到这个:

    protected List<String> a;
    @XmlElement(type = Integer.class)
    protected List<Integer> b;
    @XmlMixed
    protected List<String> content;
    

    将在下一个版本(0.9.0)中。

    【讨论】:

    • 你没有回答我的问题。我试图在不丢失属性或子节点的情况下获取名称元素的文本内容。我并不是要批评,但您似乎只是在没有真正考虑我的问题的情况下为您的网站发布了广告。
    • 好吧,我认为“这个生成的 java 类存在几个问题。首先,它创建 List 内容;而不是为分隔符、前缀和后缀创建单独的属性。”是你问题的一部分,不是吗?我“宣传”的插件正是针对这一点。您在问如何在最后一行中分隔属性,所讨论的插件正是这样做的。你还觉得我的回答不合适吗?你元素的文本内容应该在你得到的List&lt;Serializable&gt;属性中,毕竟String就是Serializable
    • 我知道我可以通过去掉 xsd 中的 mixed 属性来去掉 XmlElementRefs。但是这样做让我无法访问name 元素的文本组件。我的问题是如何在通过删除mixed 摆脱XmlElementRefs 后访问name 元素的文本组件。我不明白 oracle 的架构师怎么会忽略这一点,以至于需要添加第三方库。
    • 上面的代码生成的ON类没有getContent()方法,即使我删除了定义JAXB的类参数的xsdmixed属性.
    • getContent() 应该是元素文本内容的字符串。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-17
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    • 2018-08-09
    • 2021-09-02
    相关资源
    最近更新 更多