xsi:type 属性中未显示通过 QName 定义的命名空间,导致验证失败
Namespace defined through QName is not shown in xsi:type attribute leading to validation failure
这是我的问题。
我有一个 xsd,其中通过使用 xs:extension 来满足多态性的需求,如下所示:
<xs:complexType name="abstract_item" abstract="true">
<xs:sequence>
<xs:element name="blabla" type="xs:string" minOccurs="1" maxOccurs="1">
</xs:sequence>
</xs:complexType>
<xs:complexType name="itemA">
<xs:complexContent>
<xs:extension base="abstract_item">
<xs:sequence>
<xs:element name="blabla1" type="xs:string" minOccurs="0" maxOccurs="1">
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="itemB">
<xs:complexContent>
<xs:extension base="abstract_item">
<xs:sequence>
<xs:element name="blabla2" type="xs:date" minOccurs="0" maxOccurs="1">
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
JaxB classes 似乎是使用 xjc 正确生成的(两个 classes ItemA 和 ItemB 扩展了一个抽象 class AbstractItem)
在编组期间,使用 QName 指定命名空间(不能没有,因为它是我必须使用的框架的一部分......)
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
JAXBContext context = JAXBContext.newInstance(retour.getClass());
Marshaller marshaller = context.createMarshaller();
QName qtag = new QName(retour.getNameSpace(), retour.getName());
marshaller.marshal(new JAXBElement(qtag, retour.getClass(), retour), document);
return document.getDocumentElement();
生成的 XML 类似于:
<ns2:retour xmlns:ns2="https://my.custom.namespace">
<items>
<item xsi:type="itemA" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<blabla>test</blabla>
<blabla1>A</blabla1>
</item>
<item xsi:type="itemB" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<blabla>test</blabla>
<blabla2>01.01.2022</blabla2>
</item>
</items>
</ns2:retour>
此 xml 对于 xsd 无效,因为类型 itemA 和 itemB 未知。
这里预期的是 xsi:type="ns2:itemA"
resp。 xsi:type="ns2:itemB"
是否有注释允许强制 jaxb 使用编组时给定的 QName 命名空间注释 xsi:type?
我设法通过在包信息中添加命名空间前缀来强制实施它:
@javax.xml.bind.annotation.XmlSchema(namespace ="https://my.custom.namespace")
package the.package.containing.my.jaxb.classes;
添加之后,生成的 xml 包含 xsi:type="ns2:itemB"
而不是预期的 xsi:type="itemB"
。
在两个不同的地方(包信息)和 QName(由我正在使用的框架强制执行)中定义名称空间是不正确的。
但是,它确实有效...
这是我的问题。
我有一个 xsd,其中通过使用 xs:extension 来满足多态性的需求,如下所示:
<xs:complexType name="abstract_item" abstract="true">
<xs:sequence>
<xs:element name="blabla" type="xs:string" minOccurs="1" maxOccurs="1">
</xs:sequence>
</xs:complexType>
<xs:complexType name="itemA">
<xs:complexContent>
<xs:extension base="abstract_item">
<xs:sequence>
<xs:element name="blabla1" type="xs:string" minOccurs="0" maxOccurs="1">
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="itemB">
<xs:complexContent>
<xs:extension base="abstract_item">
<xs:sequence>
<xs:element name="blabla2" type="xs:date" minOccurs="0" maxOccurs="1">
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
JaxB classes 似乎是使用 xjc 正确生成的(两个 classes ItemA 和 ItemB 扩展了一个抽象 class AbstractItem)
在编组期间,使用 QName 指定命名空间(不能没有,因为它是我必须使用的框架的一部分......)
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
JAXBContext context = JAXBContext.newInstance(retour.getClass());
Marshaller marshaller = context.createMarshaller();
QName qtag = new QName(retour.getNameSpace(), retour.getName());
marshaller.marshal(new JAXBElement(qtag, retour.getClass(), retour), document);
return document.getDocumentElement();
生成的 XML 类似于:
<ns2:retour xmlns:ns2="https://my.custom.namespace">
<items>
<item xsi:type="itemA" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<blabla>test</blabla>
<blabla1>A</blabla1>
</item>
<item xsi:type="itemB" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<blabla>test</blabla>
<blabla2>01.01.2022</blabla2>
</item>
</items>
</ns2:retour>
此 xml 对于 xsd 无效,因为类型 itemA 和 itemB 未知。
这里预期的是 xsi:type="ns2:itemA"
resp。 xsi:type="ns2:itemB"
是否有注释允许强制 jaxb 使用编组时给定的 QName 命名空间注释 xsi:type?
我设法通过在包信息中添加命名空间前缀来强制实施它:
@javax.xml.bind.annotation.XmlSchema(namespace ="https://my.custom.namespace")
package the.package.containing.my.jaxb.classes;
添加之后,生成的 xml 包含 xsi:type="ns2:itemB"
而不是预期的 xsi:type="itemB"
。
在两个不同的地方(包信息)和 QName(由我正在使用的框架强制执行)中定义名称空间是不正确的。 但是,它确实有效...