我想解析以下xml,但item返回null。问题在于xmlns:xsd, xmlns:xsi,xmlns在item元素之后,如果我删除这些元素,我的代码可以工作,但是我从一个我没有影响的数据提供者那里获取xml。如何处理项的命名空间?我得到的最接近的答案是:jaxb:在同一个包中使用多个名称空间来解组xml,但它带有前缀,并且两个名称空间都在文件的开头声明。
<?xml version="1.0" encoding="utf-8"?>
<OAI-PMH xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.openarchives.org/OAI/2.0/">
<ListRecords>
<record>
<Item xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.cmiag.ch/PRIMO">
<Guid>5202d687891a4d6895b244b90e225ef0</Guid>
<Titel>Der sterbende Adonis: Ein Gedicht</Titel>
</Item>
</record>
<record>
<Item xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.cmiag.ch/PRIMO">
<Guid>60fced31a9b74f9989a73516ed586467</Guid>
<Titel>Dienstbüchlein</Titel>
</Item>
</record>
</ListRecords>
</OAI-PMH>
程序包信息
@XmlSchema(
namespace="http://www.openarchives.org/OAI/2.0/",
elementFormDefault = XmlNsForm.QUALIFIED,
xmlns={
@XmlNs(prefix="", namespaceURI="http://www.openarchives.org/OAI/2.0/")
}
)
package ...;
import javax.xml.bind.annotation.*;
objectfactory.java文件
@XmlRegistry
public class ObjectFactory {
public ObjectFactory() {
}
public OAIPMHtype createOAIPMHtype() {
return new OAIPMHtype();
}
public ListRecordsType createListRecordsType() {
return new ListRecordsType();
}
}
oaipmhtype.java文件
@XmlRootElement(name = "OAI-PMH", namespace = "http://www.openarchives.org/OAI/2.0/")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "OAI-PMHtype", propOrder = {
"listRecords"
})
public class OAIPMHtype {
@XmlElement(name = "ListRecords")
protected ListRecordsType listRecords;
public ListRecordsType getListRecords() {
return listRecords;
}
public void setListRecords(ListRecordsType value) {
this.listRecords = value;
}
}
listrecordstype.java文件
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ListRecordsType", propOrder = {
"record"
})
public class ListRecordsType {
@XmlElement(required = true)
protected List<RecordType> record;
public List<RecordType> getRecord() {
if (record == null) {
record = new ArrayList<RecordType>();
}
return this.record;
}
}
记录类型.java
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "recordType", propOrder = {
"Item"
})
public class RecordType {
@XmlElement(required = true, name = "Item", namespace = "http://www.cmiag.ch/PRIMO")
protected ItemType Item;
public ItemType getItemType() {
return Item;
}
public void setItemType(ItemType value) {
this.Item = value;
}
}
项目类型.java
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Item", namespace = "http://www.cmiag.ch/PRIMO", propOrder = {
"Guid",
"Titel"
})
public class ItemType {
@XmlElement(required = true)
protected String Guid;
@XmlElement(required = true)
protected String Titel;
public String getGuid() {
return Guid;
}
public void setGuid(String guid) {
this.Guid = guid;
}
public String getTitel() {
return Titel;
}
public void setTitel(String titel) {
Titel = titel;
}
}
测试类
public class OaipmhUnmarshallMain {
public static void main(String[] args) throws JAXBException, IOException {
marshalTest();
unMarshalingExample();
}
private static void unMarshalingExample() throws JAXBException {
JAXBContext jc = JAXBContext.newInstance(OAIPMHtype.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/main/resources/input.xml");
OAIPMHtype oai = (OAIPMHtype) unmarshaller.unmarshal(xml);
System.out.println();
for(RecordType rec : oai.getListRecords().getRecord())
{
System.out.println("Item Guid: " + rec.getItemType().getGuid());
System.out.println("Item Type: " + rec.getItemType().getTitel());
}
}
private static void marshalTest() throws JAXBException {
JAXBContext jc =
JAXBContext.newInstance(OAIPMHtype.class);
// Item
ItemType item = new ItemType();
item.setGuid("oi987llkj");
item.setTitel("Hallo Welt");
// Record
RecordType rec = new RecordType();
rec.setItemType(item);
// The list inside ListRecordsType
List<RecordType> records = new ArrayList<RecordType>();
records.add(rec);
// ListRecordsType
ListRecordsType list = new ListRecordsType();
list.setRecord(records);
// OAIPMHtype
OAIPMHtype oai = new OAIPMHtype();
oai.setListRecords(list);
Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
m.marshal(oai, System.out);
}
}
控制台输出
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<OAI-PMH xmlns="http://www.openarchives.org/OAI/2.0/" xmlns:ns2="http://www.cmiag.ch/PRIMO">
<ListRecords>
<record>
<ns2:Item>
<ns2:Guid>oi987llkj</ns2:Guid>
<ns2:Titel>Hallo Welt</ns2:Titel>
</ns2:Item>
</record>
</ListRecords>
</OAI-PMH>
Item Guid: 5202d687891a4d6895b244b90e225ef0
Item Type: Der sterbende Adonis: Ein Gedicht
Item Guid: 60fced31a9b74f9989a73516ed586467
Item Type: Dienstbüchlein
在最终解决方案中,我将从url读取xml。
上面的问题更新了我更改了包信息,并将名称空间定义放在了包含itemtype的recordtype中。
@XmlElement(required = true, name = "Item", namespace = "cmiag.ch/PRIMO")
protected ItemType Item;
通过这个,我得到了itemtype对象,但没有得到它的子节点。
更新我不得不将名称空间也添加到itemtype类中。
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Item", namespace = "http://www.cmiag.ch/PRIMO", propOrder = {
"Guid",
"Titel"
})
public class ItemType {...}
结论编组确实有助于理解,即使在我的用例中,我只对解编组感兴趣。
包信息的命名空间是默认命名空间。如果一个元素及其子元素有不同的名称空间,我必须在它们中重写它。
原始xml和封送的xml看起来并不完全相同,但解封工作正常。
在封送的xml中有一个前缀
在封送的xml中,xmln都位于根元素
暂无答案!
目前还没有任何答案,快来回答吧!