如何使用MixedContent数据处理JAXB ComplexType?

时间:2012-09-24 15:34:44

标签: java xml xsd jaxb xjc

我有这个XML结构:

<Tax>
  <Money currency="USD">0.00</Money>
  <Description xml:lang="en">
     17.5% Non-Recoverable
    <ShortName>vatspecial</ShortName>
  </Description>
</Tax>

请注意,Description节点有MixedContent (由文字和XML组成),这是关于XSD的{​​{1}}部分节点

Description

此时一切正常,<xsd:complexType name="TaxDescriptionType"> <xsd:sequence> <xsd:element name="ShortName" type="xsd:string" /> </xsd:sequence> <xsd:attribute ref="xml:lang" /> </xsd:complexType> 输出生成的类,如XJC所示:

TaxDescriptionType

然后,通过以上package org.com.project; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlSchemaType; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; /** * <p>Java class for TaxDescriptionType complex type. * * <p>The following schema fragment specifies the expected content contained within this class. * * <pre> * &lt;complexType name="TaxDescriptionType"> * &lt;complexContent> * &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> * &lt;sequence> * &lt;element name="ShortName" type="{http://www.w3.org/2001/XMLSchema}string"/> * &lt;/sequence> * &lt;attribute ref="{http://www.w3.org/XML/1998/namespace}lang"/> * &lt;/restriction> * &lt;/complexContent> * &lt;/complexType> * </pre> * * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "TaxDescriptionType", propOrder = { "shortName" }) public class TaxDescriptionType { @XmlElement(name = "ShortName", required = true) protected String shortName; @XmlAttribute(name = "lang", namespace = "http://www.w3.org/XML/1998/namespace") @XmlJavaTypeAdapter(CollapsedStringAdapter.class) @XmlSchemaType(name = "NCName") protected String lang; /** * Gets the value of the shortName property. * * @return * possible object is * {@link String } * */ public String getShortName() { return shortName; } /** * Sets the value of the shortName property. * * @param value * allowed object is * {@link String } * */ public void setShortName(String value) { this.shortName = value; } /** * Gets the value of the lang property. * * @return * possible object is * {@link String } * */ public String getLang() { return lang; } /** * Sets the value of the lang property. * * @param value * allowed object is * {@link String } * */ public void setLang(String value) { this.lang = value; } } ,我可以解决这样的元素:

class

但问题是,我无法找到taxDescriptionType.setLang("en"); taxDescriptionType.setShortName("vatspecial"); /* missing value: 17.5% Non-Recoverable */ 的{​​{1}}或get来自set 17.5% Non-Recoverable文字的方法{{1}例如。


这是我尝试过的,但它无效:

  • 使用过的MixedContent-ComplexType属性:

XML

(我认为XJC忽略了最后一个属性)


做了一些研究,我发现了这个:

JAXB XJC compiler disregarding mixed=true on XML Schema documents

但我不确定这是否是解决这个问题的方法。其中一个答案说这是一个错误,而在另一个答案中显示了一个代码,将mixed="true"转换为<xsd:complexType name="TaxDescriptionType" mixed="true">,也许下一个情况将是关于如何处理这个问题:

MixedContent

(我真的不知道如何处理List<Serializable>元素)

2 个答案:

答案 0 :(得分:4)

正如您所提到的,您需要添加mixed属性以指示您的类型支持混合内容。如果没有指定,则您的XML内容无效:

<xsd:complexType name="TaxDescriptionType" mixed="true">
    <xsd:sequence>
        <xsd:element name="ShortName" type="xsd:string" />
    </xsd:sequence>
    <xsd:attribute ref="xml:lang" />
</xsd:complexType>

生成的TaxDescriptionType类将具有以下属性。实质上,这意味着所有非属性内容都将存储在List中。这是必要的,因为您需要一种机制来指示文本节点与元素内容的位置。

@XmlElementRef(name = "ShortName", namespace = "http://www.example.org/schema", type = JAXBElement.class)
@XmlMixed
protected List<Serializable> content;

您将使用String(表示文本节点)和JAXBElement(表示元素内容)的实例填充此列表。


<强>替代地

混合内容通常会使生活变得更加复杂。如果可能的话,我会推荐一个替代的XML表示。

<Tax>
  <Money currency="USD">0.00</Money>
  <Description xml:lang="en" ShortName="vatspecial">
    17.5% Non-Recoverable
  </Description>
</Tax>

或者

<Tax>
  <Money currency="USD">0.00</Money>
  <Description xml:lang="en">
    <LongName>17.5% Non-Recoverable</LongName>
    <ShortName>vatspecial</ShortName>
  </Description>
</Tax>

答案 1 :(得分:2)

使用mixed = true,在ObjectFactory中应该有一个像JAXBElement<ShortNameType> createTaxDescriptionTypeShortNameType(ShortNameType)这样的函数,它会为你生成可序列化的元素。

 @XmlElementDecl(namespace = "", name = "shortnametype", scope = TaxDescriptionType.class)
    public JAXBElement<ShortNameType> createTaxDescriptionTypeShortNameType(ShortNameType value) {
        return new JAXBElement<ShortNameType>(new QName("", "shortnametype"), ShortNameType.class, TaxDescriptionType.class, value);
 }