这个XML设计非常痛苦,但无论如何都需要处理。
我不能把它作为<ack>
个对象的列表,因为每个对象都有一组不同的标签,对吧?
请帮忙!
<frm>
<version>1.1.0</version>
<ack>
<id_1>--</id_1>
<pow_1 />
<temp_1 />
<state_1>fixed</state_1>
</ack>
<ack>
<id_2>0000C6F5</id_2>
<pow_2>0w</pow_2>
<temp_2>---</temp_2>
<state_2>fixed</state_2>
</ack>
<ack>
<id_3>--</id_3>
<pow_3 />
<temp_3 />
<state_3>fixed</state_3>
</ack>
<ack>
<id_4>--</id_4>
<pow_4 />
<temp_4 />
<state_4>fixed</state_4>
</ack>
<ack>
<id_5>--</id_5>
<pow_5 />
<temp_5 />
<state_5>fixed</state_5>
</ack>
<ack>
<id_6>--</id_6>
<pow_6 />
<temp_6 />
<state_6>fixed</state_6>
</ack>
<ack>
<id_7>--</id_7>
<pow_7 />
<temp_7 />
<state_7>fixed</state_7>
</ack>
<ack>
<id_8>--</id_8>
<pow_8 />
<temp_8 />
<state_8>fixed</state_8>
</ack>
<ack>
<id_9>--</id_9>
<pow_9 />
<temp_9 />
<state_9>fixed</state_9>
</ack>
<ack>
<id_10>--</id_10>
<pow_10 />
<temp_10 />
<state_10>fixed</state_10>
</ack>
</frm>
答案 0 :(得分:4)
以下是使用JAXB和StAX组合支持此用例的方法。
<强>演示强>
我们可以使用StreamReaderDelegate
来更改元素名称的报告方式。我们将使用它删除_
及其后的所有内容。
import javax.xml.bind.*;
import javax.xml.stream.*;
import javax.xml.stream.util.StreamReaderDelegate;
import javax.xml.transform.stream.StreamSource;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Frm.class);
XMLInputFactory xif = XMLInputFactory.newFactory();
StreamSource source = new StreamSource("src/forum18096385/input.xml");
XMLStreamReader xsr = xif.createXMLStreamReader(source);
xsr = new StreamReaderDelegate(xsr) {
@Override
public String getLocalName() {
String localName = super.getLocalName();
int underScoreIndex = localName.indexOf('_');
if(underScoreIndex >= 0) {
return localName.substring(0, underScoreIndex);
}
return localName;
}
};
Unmarshaller unmarshaller = jc.createUnmarshaller();
Frm frm = (Frm) unmarshaller.unmarshal(xsr);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(frm, System.out);
}
}
<强> input.xml中强>
您问题中的XML。
<强>输出强>
由于我们将映射到修改后的XML,如果我们编组结果,它将看起来与输入不同。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<frm>
<version>1.1.0</version>
<ack>
<id>--</id>
<pow></pow>
<temp></temp>
<state>fixed</state>
</ack>
<ack>
<id>0000C6F5</id>
<pow>0w</pow>
<temp>---</temp>
<state>fixed</state>
</ack>
<ack>
<id>--</id>
<pow></pow>
<temp></temp>
<state>fixed</state>
</ack>
<ack>
<id>--</id>
<pow></pow>
<temp></temp>
<state>fixed</state>
</ack>
<ack>
<id>--</id>
<pow></pow>
<temp></temp>
<state>fixed</state>
</ack>
<ack>
<id>--</id>
<pow></pow>
<temp></temp>
<state>fixed</state>
</ack>
<ack>
<id>--</id>
<pow></pow>
<temp></temp>
<state>fixed</state>
</ack>
<ack>
<id>--</id>
<pow></pow>
<temp></temp>
<state>fixed</state>
</ack>
<ack>
<id>--</id>
<pow></pow>
<temp></temp>
<state>fixed</state>
</ack>
<ack>
<id>--</id>
<pow></pow>
<temp></temp>
<state>fixed</state>
</ack>
</frm>
以下是我们将映射到修改后的XML的Java模型。
<强> FRM 强>
import java.util.List;
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Frm {
private String version;
private List<Ack> ack;
}
<强>确认强>
import javax.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
public class Ack {
private String id;
private String pow;
private String temp;
private String state;
}
答案 1 :(得分:0)
我认为使用StAX会更简单
XMLStreamReader xr = ...
while (xr.hasNext()) {
int n = xr.next();
if (n == XMLStreamReader.START_ELEMENT)) {
String name = xr.getLocalName();
if (name.startsWith("id")) {
ack = new Ack();
ack.id = xr.getElementText();
} else if (name.startsWith("pow")) {
...
} else if (name.startsWith("state")) {
ack.state = xr.getElementText();
list.add(ack);
}
}
}