Java 如何解组包装在另一个元素中的元素
我想解组以下XML,并从中仅提取Java 如何解组包装在另一个元素中的元素,java,jaxb,Java,Jaxb,我想解组以下XML,并从中仅提取CD元素列表: <?xml version="1.0" encoding="UTF-8"?> <Root> <Header> <SomData> <Name>Name</Name> </SomData> </Header> <Message> <Dziuba
CD
元素列表:
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<Header>
<SomData>
<Name>Name</Name>
</SomData>
</Header>
<Message>
<DziubasekInfo>
<some_data>Data</some_data>
</DziubasekInfo>
<CATALOG>
<Entry>
<CD>
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR>
</CD>
</Entry>
<Entry>
<CD>
<TITLE>Hide your heart</TITLE>
<ARTIST>Bonnie Tyler</ARTIST>
<COUNTRY>UK</COUNTRY>
<COMPANY>CBS Records</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1988</YEAR>
</CD>
</Entry>
<Entry>
<CD>
<TITLE>Greatest Hits</TITLE>
<ARTIST>Dolly Parton</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>RCA</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1982</YEAR>
</CD>
</Entry>
</CATALOG>
</Message>
</Root>
如您所见,这里有3个类:
Catalog
它包装Entry
它反过来包装Cd
class.实际上,每个
条目
只包含一个Cd
条目。有没有办法消除这个包装类中的一个,只使用2个类而不是3个类
为了简化这段代码,特别是这段代码看起来有点笨拙:
e.getCdList().get(0).getArtist(),
e.getCdList().get(0).getTitle(),
e.getCdList().get(0).getPrice()
如果列表中只有一个条目,并且总是只得到一个条目,这有点愚蠢,最好这样做:
e.getCdList().getArtist(), e.getCdList().getTitle(), e.getCdList().getPrice()
任何与XML相关的映射的基本点都不是代码,而是XML(实际上是XML模式)。JAXB注释定义了模式。因此,如果您的XML具有模式 就像你所展示的:
<CATALOG>
<Entry>
<CD>
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR>
</CD>
</Entry>
...
皇帝讽刺剧
鲍勃·迪伦
美国
哥伦比亚
10.90
1985
...
那就是它的本来面目。Entry元素有CD元素。
如果要消除CD元素,则XML必须如下所示:
<CATALOG>
<Entry>
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR>
</Entry>
皇帝讽刺剧
鲍勃·迪伦
美国
哥伦比亚
10.90
1985
不多也不少。。。Java对象(带有JAXB注释)只是XML模式指示内容的反映。如果您不能更改XML,那么您必须接受它
顺便说一句:我很确定条目可能除了CD元素之外还有其他元素,比如DVD、磁带、VINIL等等。任何与XML相关的映射的基本点不是代码,而是XML(实际上是XML模式)。JAXB注释定义了模式。因此,如果您的XML具有模式 就像你所展示的:
<CATALOG>
<Entry>
<CD>
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR>
</CD>
</Entry>
...
皇帝讽刺剧
鲍勃·迪伦
美国
哥伦比亚
10.90
1985
...
那就是它的本来面目。Entry元素有CD元素。
如果要消除CD元素,则XML必须如下所示:
<CATALOG>
<Entry>
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR>
</Entry>
皇帝讽刺剧
鲍勃·迪伦
美国
哥伦比亚
10.90
1985
不多也不少。。。Java对象(带有JAXB注释)只是XML模式指示内容的反映。如果您不能更改XML,那么您必须接受它
顺便说一句:我很确定条目可能有CD以外的元素,如DVD、磁带、VINIL等。我最终用EclipseLink/Moxy和
@XmlPath(value=“Entry/CD”)
注释解决了这个问题。Cd
类与问题中的相同。这是
目录
类:
@XmlRootElement(name="CATALOG")
@XmlAccessorType(XmlAccessType.FIELD)
public class Catalog {
@XmlElement(name = "CD", type = Cd.class)
@XmlPath(value="Entry/CD")
private List<Cd> list = new ArrayList<>();
... getters/setters
}
我最终用EclipseLink/Moxy和
@XmlPath(value=“Entry/CD”)
注释解决了这个问题
Cd
类与问题中的相同。这是
目录
类:
@XmlRootElement(name="CATALOG")
@XmlAccessorType(XmlAccessType.FIELD)
public class Catalog {
@XmlElement(name = "CD", type = Cd.class)
@XmlPath(value="Entry/CD")
private List<Cd> list = new ArrayList<>();
... getters/setters
}
非常感谢。最后我自己用
@XmlPath(value=“Entry/CD”)
注释解决了这个问题,请看下面我的答案。谢谢。我最终自己用@XmlPath(value=“Entry/CD”)
注释解决了这个问题,请参见下面的答案。
@XmlRootElement(name="CATALOG")
@XmlAccessorType(XmlAccessType.FIELD)
public class Catalog {
@XmlElement(name = "CD", type = Cd.class)
@XmlPath(value="Entry/CD")
private List<Cd> list = new ArrayList<>();
... getters/setters
}
System.setProperty("javax.xml.bind.context.factory","org.eclipse.persistence.jaxb.JAXBContextFactory");
InputStream inp = getClass().getResourceAsStream("cd_catalog.xml");
assertTrue(inp != null);
XMLInputFactory xif = XMLInputFactory.newFactory();
StreamSource source = new StreamSource(inp);
XMLStreamReader xsr = xif.createXMLStreamReader(source);
while (!(xsr.isStartElement() && "CATALOG".equals(xsr.getLocalName()))) {
xsr.next();
}
JAXBContext jc = JAXBContext.newInstance(Catalog.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Catalog catalog = unmarshaller.unmarshal(xsr, Catalog.class).getValue();
System.out.println("Entries = " + catalog.getList().size());
for (Cd e : catalog.getList()) {
System.out.format("CD: %20s / %30s / %10s\n", e.getArtist(), e.getTitle(), e.getPrice());
}
xsr.close();