我有一个巨大的 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和其他一些资源,但没有任何提示如何解决这个问题。
以下是如何告诉 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
的字段/属性,可以以编程方式访问。
<?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>
<mt>SomeValidValue</mt>
</MyTypeWrapper>
<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 .../>
,如,然后实际用例将位于 XML 文档中,如MyTypeWrapper.xsd
。这就是MyTypeWrapper.xml
模式中openAttrs
的初衷。但因为XMLSchema.xsd
XMLSchema.xsd
是自反的,它支持其自身类型的扩展属性,因为它既是又是XML模式和XML文档!
我是 HiSrc 项目的维护者。