使用 Jaxb2Marshaller 编组时如何将 schemaLocation 添加到 XML 元素?

问题描述 投票:0回答:1

我目前正在尝试使用 Spring Boot 3 / Java 17 实现符合 Open Archives Harvesting 的服务。该协议是基于 XML 的,因此我在发送时从 OAI-PMH.xsd (和其他)和 JAXB2Marshaller 生成 Java 类结果。

但是,根据 XML 验证,编组响应无效,原因是非根 XML 元素上的 xsi:schemaLocation 丢失/错位:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<OAI-PMH xmlns="http://www.openarchives.org/OAI/2.0/"
    xmlns:oai="http://www.openarchives.org/OAI/2.0/oai-identifier"
    xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
    <responseDate>2024-07-03T14:02:59Z</responseDate>
    <request verb="Identify">http://localhost:4040/api/export/v1/oai/Identify</request>
    <Identify>
        <repositoryName>repositoryName</repositoryName>
        <baseURL>http://localhost:4040/api/export/v1/oai/Identify</baseURL>
        <protocolVersion>2.0</protocolVersion>
        <adminEmail>[email protected]</adminEmail>
        <earliestDatestamp>2019-05-13T15:31:39Z</earliestDatestamp>
        <deletedRecord>persistent</deletedRecord>
        <granularity>YYYY-MM-DDThh:mm:ssZ</granularity>
        <description>
            <oai:oai-identifier xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai-identifier http://www.openarchives.org/OAI/2.0/oai-identifier.xsd">
                <oai:scheme>oai</oai:scheme>
                <oai:repositoryIdentifier>publications.example.com</oai:repositoryIdentifier>
                <oai:delimiter>:</oai:delimiter>
                <oai:sampleIdentifier>oai:publications.example.com:1234</oai:sampleIdentifier>
            </oai:oai-identifier>
        </description>
    </Identify>
</OAI-PMH>

报错为:

cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'oai:oai-identifier'.xml(cvc-complex-type.2.4.c)

如果我(手动)将

xsi:schemaLocation
添加到
<oai:oai-identifier>
元素,则文档变得有效:

        <description>
            <oai:oai-identifier xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai-identifier http://www.openarchives.org/OAI/2.0/oai-identifier.xsd">
                <oai:scheme>oai</oai:scheme>
                <oai:repositoryIdentifier>publications.example.com</oai:repositoryIdentifier>
                <oai:delimiter>:</oai:delimiter>
                <oai:sampleIdentifier>oai:publications.example.com:1234</oai:sampleIdentifier>
            </oai:oai-identifier>
        </description>

如何在编组过程中自动将模式位置添加到元素中?

编组本身是通过 Spring 的 MarshallingHttpMessageConverter 完成的:

@Configuration
class WebConfig implements WebMvcConfigurer {

    @Override
    public void extendMessageConverters(
            @NonNull List<HttpMessageConverter<?>> converters) {

        var marshaller = new Jaxb2Marshaller();
        marshaller.setContextPaths(
                "org.openarchives.oai",
                "org.openarchives.oai_dc",
                "org.openarchives.oai_identifier",
                "org.purl.dc.elements");

        Map<String, ?> marshallerProperties = new HashMap<>() {
            {
                put(Marshaller.JAXB_FORMATTED_OUTPUT, true);
                put(Marshaller.JAXB_SCHEMA_LOCATION,
                        "http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd");
            }
        };

        marshaller.setMarshallerProperties(marshallerProperties);

        var converter = new MarshallingHttpMessageConverter(marshaller);
        converter.setDefaultCharset(StandardCharsets.UTF_8);
        
        converters.add(0, converter);

    }
}
java xml spring-boot jaxb
1个回答
0
投票

所以,回答我自己的问题:

只需向 Marshaller 添加更多名称空间 URI/模式位置即可。在文件

WebConfig
中,所需的更改是:

        marshaller.setMarshallerProperties(new HashMap<String, Object>() {
            {
                put(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
                put(Marshaller.JAXB_ENCODING, StandardCharsets.UTF_8.name());
                put(Marshaller.JAXB_SCHEMA_LOCATION,
                        "http://www.openarchives.org/OAI/2.0/ https://www.openarchives.org/OAI/2.0/OAI-PMH.xsd " +
                                "http://www.openarchives.org/OAI/2.0/oai_dc/ https://www.openarchives.org/OAI/2.0/oai_dc.xsd");
            }
        });
© www.soinside.com 2019 - 2024. All rights reserved.