jaxb用两个名称空间(一个在开始处,一个在元素处)来解组xml,没有前缀

3htmauhk  于 2021-06-29  发布在  Java
关注(0)|答案(0)|浏览(216)

我想解析以下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都位于根元素

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题