gpt4 book ai didi

java - JAXB/XSD : Number instead of Element name

转载 作者:行者123 更新时间:2023-12-02 01:36:13 26 4
gpt4 key购买 nike

我必须从 xml 文件创建 Java 对象(在转换之前我无法对其进行编辑),因此我认为最好创建一个 XSD,然后通过 JAXB 解码该文件。问题是,该 XML 中有一些元素的格式如下:

<parent-element>
<id-00001>...</id-00001>
<id-00002>...</id-00002>
...
</parent-element>

所以基本上我有一个 xml 元素列表,元素的“名称”是列表内的顺序。每个列表中的元素数量可能是无限的。是否可以使用 JAXB 对其进行解码,或者我是否必须使用 XML 读取器并循环遍历元素? “id-XXXXX”元素在内部都以相同的方式格式化,因此如果将其格式化为“”,则可能没有任何问题。

提前致谢!

最佳答案

我猜你的XML有效负载如下所示:

<root>
<parent-element>
<id-00001>value 1</id-00001>
<id-00002>value 2</id-00002>
</parent-element>
</root>

要读取具有动态名称的节点,我们需要编写自定义适配器( javax.xml.bind.annotation.adapters.XmlAdapter )。假设该模型如下所示:

@XmlRootElement(name = "root")
@XmlAccessorType(XmlAccessType.FIELD)
class Root {

@XmlElement(name = "parent-element")
@XmlJavaTypeAdapter(IdsXmlAdapter.class)
private MultiItemList list;

// getters, setters, toString
}

class MultiItemList {

private List<String> ids;

// getters, setters, toString
}

对于以上XMLPOJO模型自定义适配器可能如下所示:

class IdsXmlAdapter extends XmlAdapter<Object, MultiItemList> {

@Override
public MultiItemList unmarshal(Object v) {
Element element = (Element) v;
NodeList childNodes = element.getChildNodes();
List<String> ids = new ArrayList<>(childNodes.getLength());
for (int i = 0; i < childNodes.getLength(); i++) {
Node item = childNodes.item(i);
if (item.getNodeName().equals("#text")) {
continue;
}
ids.add(item.getTextContent());
}

MultiItemList multiItemList = new MultiItemList();
multiItemList.setIds(ids);
return multiItemList;
}

@Override
public Object marshal(MultiItemList v) throws Exception {
return null; // Implement if needed
}
}

使用示例:

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;

public class JaxbApp {

public static void main(String[] args) throws Exception {
File xmlFile = new File("./resource/test.xml").getAbsoluteFile();

JAXBContext jaxbContext = JAXBContext.newInstance(Root.class);

Object unmarshal = jaxbContext.createUnmarshaller().unmarshal(new FileReader(xmlFile));
System.out.println(unmarshal);
}
}

打印:

Root{list=Root{ids=[value 1, value 2]}}

注意,您不能直接实现XmlAdapter<Element, MultiItemList>适配器因为异常:

Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
org.w3c.dom.Element is an interface, and JAXB can't handle interfaces.
this problem is related to the following location:
at org.w3c.dom.Element

另请参阅:

关于java - JAXB/XSD : Number instead of Element name,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55221527/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com