JAXB-@XmlMixed 用于读取@XmlValue 和@XmlElement [英] JAXB- @XmlMixed usage for reading @XmlValue and @XmlElement

查看:33
本文介绍了JAXB-@XmlMixed 用于读取@XmlValue 和@XmlElement的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看到这里发布了一个类似的问题,但它并没有帮助我解决问题,所以我在这里发布我的问题,看看是否有人可以修改我的代码以使其工作.

问题:如何访问混合内容字符串值并将其保存在 setPhrase(String value) 方法中?

caption.xml:

<body xmlns:prefix3="link3"><div prefix1:att1="att1" prefix1:att2="att2"><prefix3:info att1="att1" att2="att2"/><p att1="att1" att2="att2" att3="att3"><prefix3:status att1="att1" att2="att2"/>你好,世界.</p>

</tt>

Caption.java:

package com;导入 javax.xml.bind.annotation.XmlElement;导入 javax.xml.bind.annotation.XmlElementRef;导入 javax.xml.bind.annotation.XmlElementRefs;导入 javax.xml.bind.annotation.XmlMixed;导入 javax.xml.bind.annotation.XmlRootElement;导入 javax.xml.bind.annotation.XmlType;@XmlRootElement(name = "p")@XmlType(propOrder = { "att1", "att2", "att3", "phrase", "subelement"})公共类标题{私人字符串 att1;私人字符串 att2;私人字符串 att3;私人字符串短语;private Subelement subelement = new Subelement();@XmlMixedpublic void setPhrase(字符串值){this.phrase = 值;}公共字符串 getPhrase(){返回短语;}@XmlElementRefs({@XmlElementRef(name = "subelement", type = Subelement.class)})@XmlMixedpublic void setSubelement(Subelement subelement){this.subelement = 子元素;}公共子元素 getSubelement(){返回子元素;}@XmlAttributepublic void setAtt1( String att1 ){this.att1 = att1;}公共字符串 getAtt1(){返回 att1;}@XmlAttributepublic void setAtt2( String att2 ){this.att2 = att2;}公共字符串 getAtt2(){返回 att2;}@XmlAttributepublic void setAtt3( String att3 ){this.att3 = att3;}公共字符串 getAtt3(){返回 att3;}}

在使用 JAXB unmarshall 和 marshall 之后,除了实际的短语Hello World."之外,我能够将所有内容转换为对象并保存下来.我知道我必须对这个复杂的元素使用某种 @XmlMixed,但我无法弄清楚.

我当前的 output.xml:

<body xmlns:prefix3="link3"><div prefix1:att1="att1" prefix1:att2="att2"><prefix3:info att1="att1" att2="att2"/><p att1="att1" att2="att2" att3="att3"><prefix3:status att1="att1" att2="att2"/></p>

</tt>

Desire output.xml:(与caption.xml 相同)

<body xmlns:prefix3="link3"><div prefix1:att1="att1" prefix1:att2="att2"><prefix3:info att1="att1" att2="att2"/><p att1="att1" att2="att2" att3="att3"><prefix3:status att1="att1" att2="att2"/>你好,世界.</p>

</tt>

预先感谢任何帮助我访问此值并将其保存在 setPhrase(String value) 方法中.

解决方案

我会试着用一个例子来回答你的问题:

input.xml

我们将在此示例中使用以下 XML 文档.root 元素具有混合内容.混合内容意味着文本节点可以与元素混合出现.由于可以出现多个文本节点,因此一元属性不太适合.

<root/>你好<root/>世界<root/></root>

演示

以下代码将用于读取 XML 到对象表单,然后将其写回 XML.

包论坛10940267;导入 java.io.File;导入 javax.xml.bind.*;公开课演示{public static void main(String[] args) 抛出异常 {JAXBContext jc = JAXBContext.newInstance(Root.class);unmarshaller unmarshaller = jc.createUnmarshaller();File xml = new File("src/forum10940267/input.xml");Root root = (Root) unmarshaller.unmarshal(xml);Marshaller marshaller = jc.createMarshaller();marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,真);marshaller.marshal(root, System.out);}}

用例 #1 - 一个包含混合内容的列表

@XmlMixed 最常与另一个注释一起使用,因此结果 List 包含元素和文本内容.这样做的一个优点是保持顺序,以便文档可以往返.

包论坛10940267;导入 java.util.*;导入 javax.xml.bind.annotation.*;@XmlRootElement公共类根{私人列表<对象>混合内容 = 新的 ArrayList();@XmlElementRef(name="root", type=Root.class)@XmlMixed公共列表<对象>getMixedContent() {返回混合内容;}public void setMixedContent(ListmixedContent) {this.mixedContent = 混合内容;}}

输出

输出与输入匹配.

<root/>你好<root/>世界<root/></root>

用例 #2 - 混合内容的单独列表

您还可以为文本内容引入单独的列表属性.

包论坛10940267;导入 java.util.*;导入 javax.xml.bind.annotation.*;@XmlRootElement公共类根{私人列表<对象>混合内容 = 新的 ArrayList();私人列表<字符串>文本;@XmlElementRef(name="root", type=Root.class)公共列表<对象>getMixedContent() {返回混合内容;}public void setMixedContent(ListmixedContent) {this.mixedContent = 混合内容;}@XmlMixed公共列表<字符串>获取文本(){返回文本;}public void setText(List text) {this.text = 文字;}}

输出

输出不再与输入匹配.

<root/><root/><root/>你好世界</root>

用例 #3 - 文本内容的字符串属性

由于文本节点可以在混合内容中多次出现,因此非 List 属性不太适合,并且看起来好像忽略了 @XmlMixed 注释.

包论坛10940267;导入 java.util.*;导入 javax.xml.bind.annotation.*;@XmlRootElement公共类根{私人列表<对象>混合内容 = 新的 ArrayList();私人字符串文本;@XmlElementRef(name="root", type=Root.class)公共列表<对象>getMixedContent() {返回混合内容;}public void setMixedContent(ListmixedContent) {this.mixedContent = 混合内容;}@XmlMixed公共字符串 getText() {返回文本;}公共无效集文本(字符串文本){this.text = 文字;}}

输出

<root/><root/><root/></root>

I saw a similar question being posted here, yet it did not help me solve the problem so I am posting my question here to see if someone can modify my code to make it work.

Question: How to access mixed content String value and save it in setPhrase(String value) method?

caption.xml:

<?xml version="1.0" encoding="UTF-8"?>
<tt xmlns="link1" xmlns:prefix2="link2" prefix1:att1="att1">
    <head>
        <styling>
            <style prefix1:att1="att1" prefix2:att2="att2" prefix2:att3="att3" prefix2:att4="att4" />
        </styling>
        <layout />
    </head>
    <body xmlns:prefix3="link3">
        <div prefix1:att1="att1" prefix1:att2="att2">
            <prefix3:info att1="att1" att2="att2" />
            <p att1="att1" att2="att2" att3="att3">
                <prefix3:status att1="att1" att2="att2" />
                Hello World.
            </p>
        </div>
    </body>
</tt>

Caption.java:

package com;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlElementRefs;
import javax.xml.bind.annotation.XmlMixed;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(name = "p")
@XmlType(propOrder = { "att1", "att2", "att3", "phrase", "subelement"})
public class Caption {
    private String  att1;
    private String  att2;
    private String  att3;
    private String  phrase;
    private Subelement subelement = new Subelement();

   @XmlMixed
   public void setPhrase(String value)
   {
      this.phrase = value;
   }
   public String getPhrase()
   {
      return phrase;
   }

   @XmlElementRefs({@XmlElementRef(name = "subelement", type = Subelement.class)})
   @XmlMixed
   public void setSubelement(Subelement subelement )
   {
      this.subelement = subelement;
   }
   public Subelement getSubelement()
   {
      return subelement;
   }

   @XmlAttribute
   public void setAtt1( String att1 )
   {
      this.att1 = att1;
   }
   public String getAtt1()
   {
      return att1;
   }

   @XmlAttribute
   public void setAtt2( String att2 )
   {
      this.att2 = att2;
   }
   public String getAtt2()
   {
      return att2;
   }

   @XmlAttribute
   public void setAtt3( String att3 )
   {
      this.att3 = att3;
   }
   public String getAtt3()
   {
      return att3;
   }
}

After using JAXB unmarshall and marshall I am able to get everything converted into and object and saved accorderling, except for the actual phrase "Hello World.". I know I must use some sort of @XmlMixed for this complex element but I cannot figure it out.

My current output.xml:

<?xml version="1.0" encoding="UTF-8"?>
<tt xmlns="link1" xmlns:prefix2="link2" prefix1:att1="att1">
    <head>
        <styling>
            <style prefix1:att1="att1" prefix2:att2="att2" prefix2:att3="att3" prefix2:att4="att4" />
        </styling>
        <layout />
    </head>
    <body xmlns:prefix3="link3">
        <div prefix1:att1="att1" prefix1:att2="att2">
            <prefix3:info att1="att1" att2="att2" />
            <p att1="att1" att2="att2" att3="att3">
                <prefix3:status att1="att1" att2="att2" />
            </p>
        </div>
    </body>
</tt>

Desire output.xml: (same as caption.xml)

<?xml version="1.0" encoding="UTF-8"?>
<tt xmlns="link1" xmlns:prefix2="link2" prefix1:att1="att1">
    <head>
        <styling>
            <style prefix1:att1="att1" prefix2:att2="att2" prefix2:att3="att3" prefix2:att4="att4" />
        </styling>
        <layout />
    </head>
    <body xmlns:prefix3="link3">
        <div prefix1:att1="att1" prefix1:att2="att2">
            <prefix3:info att1="att1" att2="att2" />
            <p att1="att1" att2="att2" att3="att3">
                <prefix3:status att1="att1" att2="att2" />
                Hello World.
            </p>
        </div>
    </body>
</tt>

Thanks in advance to any help I may get to access this value and save it in setPhrase(String value) method.

解决方案

I'll try to answer your question with an example:

input.xml

We will use the following XML document for this example. The root element has mixed content. Having mixed conent means that text nodes can appear mixed in with the elements. Since more than one text node can appear a unary property isn't a good fit.

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <root/>
    Hello
    <root/>
    World
    <root/>
</root>

Demo

The following code will be used in to read in the XML to object form and then write it back to XML.

package forum10940267;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum10940267/input.xml");
        Root root = (Root) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(root, System.out);
    }

}

USE CASE #1 - One List to Hold Mixed Content

@XmlMixed is most often used to with another annotation, so that the resulting List contains both element and text content. One advantage of this is that order is maintained so that the document can be round tripped.

package forum10940267;

import java.util.*;
import javax.xml.bind.annotation.*;

@XmlRootElement
public class Root {

    private List<Object> mixedContent = new ArrayList<Object>();

    @XmlElementRef(name="root", type=Root.class)
    @XmlMixed
    public List<Object> getMixedContent() {
        return mixedContent;
    }

    public void setMixedContent(List<Object> mixedContent) {
        this.mixedContent = mixedContent;
    }

}

Output

The output matches the input.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
    <root/>
    Hello
    <root/>
    World
    <root/>
</root>

USE CASE #2 - Separate List for Mixed Content

You can can also introduce a separate list property for the text content.

package forum10940267;

import java.util.*;
import javax.xml.bind.annotation.*;

@XmlRootElement
public class Root {

    private List<Object> mixedContent = new ArrayList<Object>();
    private List<String> text;

    @XmlElementRef(name="root", type=Root.class)
    public List<Object> getMixedContent() {
        return mixedContent;
    }

    public void setMixedContent(List<Object> mixedContent) {
        this.mixedContent = mixedContent;
    }

    @XmlMixed
    public List<String> getText() {
        return text;
    }

    public void setText(List<String> text) {
        this.text = text;
    }

}

Output

The output no longer matches the input.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
    <root/>
    <root/>
    <root/>

    Hello

    World

</root>

USE CASE #3 - String Property for Text Content

Since text nodes can occur multiple times in mixed content, a non-List property isn't a good fit and it appears as though the @XmlMixed annotation is being ignored.

package forum10940267;

import java.util.*;
import javax.xml.bind.annotation.*;

@XmlRootElement
public class Root {

    private List<Object> mixedContent = new ArrayList<Object>();
    private String text;

    @XmlElementRef(name="root", type=Root.class)
    public List<Object> getMixedContent() {
        return mixedContent;
    }

    public void setMixedContent(List<Object> mixedContent) {
        this.mixedContent = mixedContent;
    }

    @XmlMixed
    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

}

Output

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
    <root/>
    <root/>
    <root/>
</root>

这篇关于JAXB-@XmlMixed 用于读取@XmlValue 和@XmlElement的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆