使用xjc向jaxb类添加附加属性

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

我有一个巨大的 xsd 文件,我想使用 xjc 将其转换为 jaxb 类。我已经成功完成了这一点,既使用 Maven,又手动使用 xjc.sh 脚本。

但我确实有一个非常具体的问题,我正在努力寻找一个好的解决方案。问题来了:

我的 xsd 中有很多简单类型定义,如下所示:

<xsd:simpleType name="MyType" abc:reference="https://example.com/valid_values.xml">
 <xsd:restriction base="xsd:string"/>
</xsd:simpleType>

在这种情况下,simpleType [定义

MyType
类型的
xsd:string
] 有一个附加属性
abc:reference
,其值为 url 常量。该 url 包含该
MyType
字符串可以具有的所有有效值。

现在,当我生成 jaxb 类时,我丢失了此信息,因为它没有以任何方式包含在 java 类中。如果没有这些信息,我将无法生成测试数据(xml 文件)。

如何告诉 xjc 在 jaxb 类中包含此 url,例如

public static String
?或者任何其他方式,只要我能够从java源访问这个url。

解决方案不是定义枚举或嵌入这些值,因为它们是外部提供的并被许多其他人使用。

我的架构如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="urn:my.company:v2" xmlns:abc="http://www.mycompany.no/xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="urn:my.company:v2">

<xsd:simpleType name="MyType" abc:reference="https://example.com/valid_values.xml">
 <xsd:restriction base="xsd:string"/>
</xsd:simpleType>


 <xsd:complexType name="MyTypeWrapper">
        <xsd:sequence>
            <xsd:element name="mt" type="MyType"/>
        </xsd:sequence>
    </xsd:complexType>

</xsd:schema>

我已经浏览了https://docs.oracle.com/javase/tutorial/jaxb/intro/custom.html和其他一些资源,但没有任何提示如何解决这个问题。

jaxb xjc maven-jaxb2-plugin jaxb2-maven-plugin
1个回答
0
投票

以下是如何告诉 xjc 在 JAXB 类中包含 (

abc:reference
) URL,以任何方式,只要可以从 java 源访问该值即可。

此未编组实例中的代码可使用该 URL:

public class OpenAttrs implements Serializable {

    @XmlAnyAttribute
    private Map<QName, String> otherAttributes = new HashMap<>();

    public Map<QName, String> getOtherAttributes() {
        return otherAttributes;
    }
}

下载 (zip) 包含一个独立的 Maven 项目,用于演示 anyAttribute 的解组。这种类型的属性用于允许将来自其他命名空间的属性添加到由 user 模式定义的 XML document 中。此示例表明它也可以在 XML schema 本身中使用,以声明来自其他名称空间的属性。

执行

将下载的文件解压到本地文件夹后,您可以使用以下命令运行测试:

mvn -Ptest clean test

或者使用以下命令执行示例应用程序:

mvn -Pexec clean compile exec:java

输出显示执行结果。

说明

鉴于下面的 XSD 带有一个名为

simpleType
MyType
,它从非架构命名空间声明了 other 属性 (
abc:reference
),我们可以使用
org.patrodyne.jvnet:hisrc-higherjaxb-w3c-xmlschema-v1_0:jar 中预编译的 JAXB 类
在运行时将 XSD 解组为 XML 架构实例(即 XML 文档)。与任何其他未编组的对象一样,该属性成为名为
otherAttributes
的字段/属性,可以以编程方式访问

MyTypeWrapper.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema
    targetNamespace="urn:my.company:v2"
    xmlns="urn:my.company:v2"
    xmlns:abc="http://www.mycompany.no/xsd"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    attributeFormDefault="unqualified"
    elementFormDefault="qualified"
>
    <xsd:simpleType name="MyType"
        abc:reference="https://example.com/valid_values.xml"
    >
        <xsd:restriction base="xsd:string"/>
    </xsd:simpleType>

    <xsd:complexType name="MyTypeWrapper">
        <xsd:sequence>
            <xsd:element name="mt" type="MyType"/>
        </xsd:sequence>
    </xsd:complexType>

</xsd:schema>

MyTypeWrapper.xml

<MyTypeWrapper>
    <mt>SomeValidValue</mt>
</MyTypeWrapper>

讨论

在 XML 模式中,

<anyAttribute>
标签使我们能够使用模式中未指定的属性来扩展 XML 文档。 <anyAttribute>
 元素用于制作可扩展文档。它允许文档包含未在主 XML 模式中声明的其他元素。

用于定义

MyTypeWrapper.xsd

MyTypeWrapper
 文件本身
是一个 XML 文件,其自己的架构由 "http://www.w3.org/2001/XMLSchema" 定义。
事实上,

XMLSchema.xsd

是一个

自描述
模式。它使用与 user 模式
<schema\>
使用的相同标签(
<element/>
<complexType/>
MyTypeWrapper.xsd 等)来定义其内容。区别在于
XMLSchema.xsd
的内容是自反的
<schema\>
<element/>
<complexType/>
等,而
MyTypeWrapper.xsd
的内容是用户定义的:
MyTypeWrapper
MyType

注意:因为
XMLSchema

是一个

自描述 
模式,所以设计用于支持 user 模式的每个标签都会成为 XMLSchema 支持的标签。

具体到本次讨论,
XMLSchema.xsd

定义了一个名为

complexType
openAttrs
,几乎所有模式类型都扩展了它,以允许将来自其他命名空间的属性添加到用户模式中。

来自 XMLSchema.xsd 的 OpenAttrs <?xml version='1.0' encoding='UTF-8'?> <!-- XML Schema schema for XML Schemas: Part 1: Structures --> <xs:schema version="1.0" xml:lang="EN" targetNamespace="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:hfp="http://www.w3.org/2001/XMLSchema-hasFacetAndProperty" elementFormDefault="qualified" blockDefault="#all" > ... <xs:complexType name="openAttrs"> <xs:annotation> <xs:documentation> This type is extended by almost all schema types to allow attributes from other namespaces to be added to user schemas. </xs:documentation> </xs:annotation> <xs:complexContent> <xs:restriction base="xs:anyType"> <xs:anyAttribute namespace="##other" processContents="lax"/> </xs:restriction> </xs:complexContent> </xs:complexType> ... </xs:schema>

正是这个 
openAttrs

定义允许

abc:reference
成为
xsd:simpleType
模式中
MyTypeWrapper.xsd
的有效属性。

MyType 作为 MyTypeWrapper.xsd 中的

simpleType


<xsd:simpleType name="MyType" abc:reference="https://example.com/valid_values.xml">
    <xsd:restriction base="xsd:string"/>
</xsd:simpleType>

在这个定义中需要注意的重要一点是,
abc:reference

XMLSchema.xsd
的扩展,而不是用户模式的扩展
MyTypeWrapper.xsd

注意:
通常

,模式设计者会在用户模式的元素/类型中声明 <xsd:anyAttribute .../>,如

MyTypeWrapper.xsd
,然后实际用例将位于 XML 文档中,如
MyTypeWrapper.xml
。这就是
openAttrs
模式中
XMLSchema.xsd
的初衷。但因为
XMLSchema.xsd
自反的,它支持其自身类型的扩展属性,因为它既是又是XML模式和XML文档!

免责声明:

我是 HiSrc 项目的维护者。

© www.soinside.com 2019 - 2024. All rights reserved.