使用 JAXB 解组多次出现的 XML 元素

Posted

技术标签:

【中文标题】使用 JAXB 解组多次出现的 XML 元素【英文标题】:Unmarshall XML element that occurs more than once using JAXB 【发布时间】:2021-10-18 17:02:38 【问题描述】:

我正在尝试将 XML 文档解组到我的模型中。问题是我有一个 XML 元素 <additional_detail> 在 XML 文档中多次出现。当我解组 XML 文档时,JSON 元素的值是最后一次出现的 <additional_detail>。我想要实现的是让它们全部用逗号分隔。

文档示例

.
.
.
<additional_detail>
 160cm
</additional_detail>
<additional_detail>
200KG
</additional_detail>
.
.
.

我的 java 模型中有:

@XmlElement(name = "additional_detail", namespace = NAME_SPACE)
private String additionalDetail;

【问题讨论】:

使用字符串列表,然后您可以从那里生成 CSV 或您想要的 ibytecode.com/blog/… 或 google jaxb xml 到对象列表将为您提供大量解决方案 这种情况有点不同,我所说的情况,所有出现的元素都在根级别,而不是分组在一个名为 的元素下,例如 【参考方案1】:

希望下面的例子能有所帮助

xml

    <Example>
    <detail>1</detail>
    <detail>2</detail>
    <detail>3</detail>
    </Example>

代码

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

public class JaxBUnmarshalExample 
    public static void main(String[] args) 
        try 
            File file = new File("file.xml");
            JAXBContext jaxbContext = JAXBContext.newInstance(Example.class);
            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
            Example que = (Example) jaxbUnmarshaller.unmarshal(file);
            System.out.println(que.details);
         catch (JAXBException e) 
            e.printStackTrace();
        

    



@XmlRootElement(name = "Example")
class Example  
    List<String> details = new ArrayList<String>();
    String detail;  
    @XmlElement(name = "detail")
    public String getDetail()      
        return detail;
    
    /*
     here adding items in list later list can be used  
    */ 
    public void setDetail(String detail) 
        details.add(detail);
        this.detail = detail;
    

【讨论】:

谢谢,这真的很有帮助。【参考方案2】:

正如评论中提到的,您应该使用List 来捕获在 XML 中具有相同标签的所有信息。以下是显示类似xml示例的示例:

XML:

<root>
    <additional_detail>160cm</additional_detail>
    <additional_detail>200KG</additional_detail>
</root>

父类:

@XmlRootElement(name = "root")
@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class Parent 
    @XmlElement(name = "additional_detail")
    List<String> additional_detail;


主类:

public class Main 
    public static void main(String[] args) throws JAXBException, XMLStreamException 
        final InputStream inputStream = Main.class.getClassLoader().getResourceAsStream("action.xml");
        final XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
        final Unmarshaller unmarshaller = JAXBContext.newInstance(Parent.class).createUnmarshaller();
        final Parent parent = unmarshaller.unmarshal(xmlStreamReader, Parent.class).getValue();
        System.out.println(parent.toString());

        Marshaller marshaller = JAXBContext.newInstance(Parent.class).createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        marshaller.marshal(parent, System.out);
    

如果您有这些列表的外部标签,例如additional_details(注意“s”),那么您可以执行以下操作:

<root>
    <additional_details>
        <additional_detail>160cm</additional_detail>
        <additional_detail>200KG</additional_detail>
    </additional_details>
</root>

父类:

@XmlRootElement(name = "root")
@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class Parent 
    @XmlElementWrapper(name = "additional_details")
    @XmlElement(name = "additional_detail")
    List<String> additional_detail;


【讨论】:

以上是关于使用 JAXB 解组多次出现的 XML 元素的主要内容,如果未能解决你的问题,请参考以下文章

使用命名空间和前缀的 JAXB 解组

从子元素开始使用JAXB解组

Jaxb2Marshaller在春天解组 - 意想不到的元素

如何跳过字段并仅使用JAXB解组该字段的特定成员?

使用 DTD 文件导致的 JAXB 解组 XML 时出错

使用 Xpath 表达式和 jaxb 解组 XML