如何将 xml 属性添加到 jaxb 带注释的类 XmlElementWrapper?

发布于 2024-09-18 00:16:13 字数 718 浏览 6 评论 0原文

我有一个带有 XmlElementWrapper 注释的类,例如

......

  @XmlElementWrapper(name="myList")
    @XmlElements({
    @XmlElement(name="myElement") }
    )
    private List<SomeType> someList = new LinkedList();

: 这段代码生成的 XML

<myList>
  <myElement> </myElement>
  <myElement> </myElement>
  <myElement> </myElement>
</myList>

到目前为止一切顺利。

但现在我需要向列表标记添加属性以获取 XML,例如

<myList number="2">
  <myElement> </myElement>
  <myElement> </myElement>
  <myElement> </myElement>
</myList>

是否有一种“智能方法可以实现此目的,而无需创建包含代表列表的新类?”

I have a class with a XmlElementWrapper annotation like:

...

  @XmlElementWrapper(name="myList")
    @XmlElements({
    @XmlElement(name="myElement") }
    )
    private List<SomeType> someList = new LinkedList();

...
This code produces XML like

<myList>
  <myElement> </myElement>
  <myElement> </myElement>
  <myElement> </myElement>
</myList>

so far so good.

But now I need to add attributes to the list tag to get XML like

<myList number="2">
  <myElement> </myElement>
  <myElement> </myElement>
  <myElement> </myElement>
</myList>

Is there a 'smart way to achieve this without creating a new class that contains represents the list?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

灵芸 2024-09-25 00:16:13

我对你的问题有更好的解决方案。

要创建 Xml Java 对象,请使用以下代码:

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

@XmlRootElement(name="myList")
public class Root {

    private String number;
    private List<String> someList;

    @XmlAttribute(name="number")
    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    @XmlElement(name="myElement")
    public List<String> getSomeList() {
        return someList;
    }

    public void setSomeList(List<String> someList) {
        this.someList = someList;
    } 

    public Root(String numValue,List<String> someListValue) {
        this();
        this.number = numValue;
        this.someList = someListValue;  
    }

    /**
     * 
     */
    public Root() {
        // TODO Auto-generated constructor stub
    }

}

要使用 JAXB 运行上述代码,请使用以下代码:

   import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.*;

public class Demo {

        public static void main(String[] args) throws Exception {
            List<String> arg = new ArrayList<String>();
            arg.add("FOO");
            arg.add("BAR");
            Root root = new Root("123", arg);

            JAXBContext jc = JAXBContext.newInstance(Root.class);
            Marshaller marshaller = jc.createMarshaller();
            marshaller.marshal(root, System.out);
        }
}

这将生成以下 XML 作为输出:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <myList number="123">
        <myElement>FOO</myElement>
        <myElement>BAR</myElement>
    </myList>

我认为这对您更有帮助。

谢谢..

I got a better solution for your question.

For making Xml Java object, use the following code:

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

@XmlRootElement(name="myList")
public class Root {

    private String number;
    private List<String> someList;

    @XmlAttribute(name="number")
    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    @XmlElement(name="myElement")
    public List<String> getSomeList() {
        return someList;
    }

    public void setSomeList(List<String> someList) {
        this.someList = someList;
    } 

    public Root(String numValue,List<String> someListValue) {
        this();
        this.number = numValue;
        this.someList = someListValue;  
    }

    /**
     * 
     */
    public Root() {
        // TODO Auto-generated constructor stub
    }

}

To run the above code using JAXB, use the following:

   import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.*;

public class Demo {

        public static void main(String[] args) throws Exception {
            List<String> arg = new ArrayList<String>();
            arg.add("FOO");
            arg.add("BAR");
            Root root = new Root("123", arg);

            JAXBContext jc = JAXBContext.newInstance(Root.class);
            Marshaller marshaller = jc.createMarshaller();
            marshaller.marshal(root, System.out);
        }
}

This will produce the following XML as the output:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <myList number="123">
        <myElement>FOO</myElement>
        <myElement>BAR</myElement>
    </myList>

I think this is more helpful you.

Thanks..

难得心□动 2024-09-25 00:16:13

MOXy JAXB 实现(我是技术主管)有一个扩展(@XmlPath) 来处理这种情况:

import java.util.*;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {

    @XmlPath("myList/@number")
    private int number;

    @XmlElementWrapper(name="myList") 
    @XmlElement(name="myElement") 
    private List<String> someList = new LinkedList<String>();

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    public List<String> getSomeList() {
        return someList;
    }

    public void setSomeList(List<String> someList) {
        this.someList = someList;
    } 

}

将生成以下 XML:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <myList number="123">
      <myElement>FOO</myElement>
      <myElement>BAR</myElement>
   </myList>
</root>

当此代码运行:

import javax.xml.bind.*;

public class Demo {

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

        Root root = new Root();
        root.setNumber(123);
        root.getSomeList().add("FOO");
        root.getSomeList().add("BAR");

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

要使用严格标准的 JAXB 代码使其工作,您将需要使用 XML 适配器:

注意:

要使用 MOXy JAXB,您需要在模型类中添加一个名为 jaxb.properties 的文件,其中包含以下条目:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

The MOXy JAXB implementation (I'm the tech lead) has an extension (@XmlPath) to handle this case:

import java.util.*;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {

    @XmlPath("myList/@number")
    private int number;

    @XmlElementWrapper(name="myList") 
    @XmlElement(name="myElement") 
    private List<String> someList = new LinkedList<String>();

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    public List<String> getSomeList() {
        return someList;
    }

    public void setSomeList(List<String> someList) {
        this.someList = someList;
    } 

}

Will produce the following XML:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <myList number="123">
      <myElement>FOO</myElement>
      <myElement>BAR</myElement>
   </myList>
</root>

When this code is run:

import javax.xml.bind.*;

public class Demo {

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

        Root root = new Root();
        root.setNumber(123);
        root.getSomeList().add("FOO");
        root.getSomeList().add("BAR");

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

To get this to work using strictly standard JAXB code you will need to use an XML Adapter:

Note:

To use MOXy JAXB you need to add a file called jaxb.properties in with your model classes with the following entry:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
围归者 2024-09-25 00:16:13

如果您不使用 MOXy 或者只是想坚持使用标准 JAXB 注释,您可以扩展 Noby 的答案以添加对通用包装类的支持。诺比的答案目前仅支持字符串列表,但举例来说,您将为几个不同的类使用相同的通用包装类。在我的示例中,我想创建一个通用的“PagedList”类,它将编组为看起来像列表的内容,但还包含有关页面偏移量和未分页列表中元素总数的信息。

此解决方案的一个缺点是您必须为要包装的每种类型的类添加额外的 @XmlElement 映射。总的来说,这可能是比为每个可分页元素创建一个新类更好的解决方案。

@XmlType
public class PagedList<T> {
    @XmlAttribute
    public int offset;

    @XmlAttribute
    public long total;

    @XmlElements({
        @XmlElement(name="order", type=Order.class),
        @XmlElement(name="address", type=Address.class)
        // additional as needed
    })
    public List<T> items;
}

@XmlRootElement(name="customer-profile")
public class CustomerProfile {
    @XmlElement
    public PagedList<Order> orders;
    @XmlElement
    public PagedList<Address> addresses;
}

编组这个例子会给你带来:

<customer-profile>
    <order offset="1" total="100">
        <order> ... </order>
        <order> ... </order>
        <order> ... </order>
        ...
    </orders>
    <addresses offset="1" total="5">
        <address> ... </address>
        <address> ... </address>
        <address> ... </address>
        <address> ... </address>
        <address> ... </address>
    <addresses>
</customer-profile>

希望有帮助。这是我至少确定的解决方案。

If you are not using MOXy or just want to stick to standard JAXB annotations, you can extend upon Noby's answer to add support for a generic wrapper class. Noby's answer only currently supports a list of strings, but say for example you're going to be using the same generic wrapper class for several different classes. In my example, I want to create a generic "PagedList" class that will marshall to something that looks like a list, but also contains information about the page offset and the total number of elements in unpaged list.

The one downside of this solution is that you have to add additional @XmlElement mappings for each type of class that will be wrapped. Overall though, probably a better solution than creating a new class for each pagable elements.

@XmlType
public class PagedList<T> {
    @XmlAttribute
    public int offset;

    @XmlAttribute
    public long total;

    @XmlElements({
        @XmlElement(name="order", type=Order.class),
        @XmlElement(name="address", type=Address.class)
        // additional as needed
    })
    public List<T> items;
}

@XmlRootElement(name="customer-profile")
public class CustomerProfile {
    @XmlElement
    public PagedList<Order> orders;
    @XmlElement
    public PagedList<Address> addresses;
}

Marshalling this example would get you:

<customer-profile>
    <order offset="1" total="100">
        <order> ... </order>
        <order> ... </order>
        <order> ... </order>
        ...
    </orders>
    <addresses offset="1" total="5">
        <address> ... </address>
        <address> ... </address>
        <address> ... </address>
        <address> ... </address>
        <address> ... </address>
    <addresses>
</customer-profile>

Hope that helps. This is the solution that I settled upon at least.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文