[英]JAXB Overwriting package-info.java: What should be “namespace”?
我們正在使用xjc生成用於XML生成的JAXB Java類。 一切工作正常,除非我們嘗試按此處所述調整生成的名稱空間前綴。 由於我們使用的JAXB版本,我們只能調整“解決方案2”並調整package-info.java。
我們擁有的結構有很多種導入:根名稱空間導入其他名稱空間,而后者又導入了第三個名稱空間。
MCVE xsds
root.xsd(導入other.xsd):
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="root" xmlns:other="other" targetNamespace="root" version="1.0">
<xs:import namespace="other" schemaLocation="other.xsd" />
<xs:element name="rootElem">
<xs:complexType>
<xs:choice>
<xs:element ref="rootElem1"/>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:element name="rootElem1" nillable="false">
<xs:complexType>
<xs:sequence>
<xs:element name="data">
<xs:complexType>
<xs:choice>
<xs:element ref="other:otherElem"/>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
other.xsd(導入third.xsd):
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:other="other" xmlns:third="third" targetNamespace="other" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0">
<xsd:import namespace="third" schemaLocation="third.xsd" />
<xsd:element name="otherElem">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="third:thirdElem" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
third.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:third="third" targetNamespace="third" elementFormDefault="qualified" attributeFormDefault="unqualified" version="1.0">
<xsd:element name="thirdElem">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="thirdData" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
有了這個
簡單的測試用例
@Test
public void test() throws JAXBException
{
Marshaller marshaller = JAXBContext.newInstance("test.jaxb.generated").createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "http://www.example.com/schema.xsd");
RootElem root = new RootElem();
RootElem1 root1 = new RootElem1();
Data d = new Data();
OtherElem other = new OtherElem();
ThirdElem thirdElem = new ThirdElem();
thirdElem.setThirdData("third");
other.setThirdElem(thirdElem);
d.setOtherElem(other);
root1.setData(d);
root.setRootElem1(root1);
Path path = Paths.get("target", "outfile.xml");
Result result = new StreamResult(path.toFile());
marshaller.marshal(root, result);
}
這導致
生成的XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns4:rootElem xmlns:ns2="other" xmlns:ns3="third" xmlns:ns4="root" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.com/schema.xsd">
<ns4:rootElem1>
<data>
<ns2:otherElem>
<ns3:thirdElem>
<ns3:thirdData>third</ns3:thirdData>
</ns3:thirdElem>
</ns2:otherElem>
</data>
</ns4:rootElem1>
</ns4:rootElem>
並且一切都很好(除了沒有關聯任何名稱空間的data
,我假設是因為這是一個內部類型)。
現在這部分是問題:這是
生成的package-info.java
@javax.xml.bind.annotation.XmlSchema(namespace = "other", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package test.jaxb.generated;
為什么給定的namespace
引用了other
? 我的根名稱空間是root
。 ( root.xsd
是我們提供給我們的Maven jaxb2-maven-plugin
的唯一文件;我們可以包含其他文件,這沒有什么區別)。
錯誤的替換package-info.java
如果我們以此覆蓋生成的:
@javax.xml.bind.annotation.XmlSchema(
namespace = "root",
xmlns = {
@javax.xml.bind.annotation.XmlNs(prefix = "t", namespaceURI = "third"),
@javax.xml.bind.annotation.XmlNs(prefix = "o", namespaceURI = "other"),
@javax.xml.bind.annotation.XmlNs(prefix = "r", namespaceURI = "root")
},
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package test.jaxb.generated;
之所以這樣做,是因為我們假設必須在此處提供根名稱空間-這是
錯誤生成的XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<r:rootElem xmlns:t="third" xmlns:o="other" xmlns:r="root" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.com/schema.xsd">
<r:rootElem1>
<data>
<r:otherElem>
<t:thirdElem>
<t:thirdData>third</t:thirdData>
</t:thirdElem>
</r:otherElem>
</data>
</r:rootElem1>
</r:rootElem>
現在,命名空間很漂亮,但是錯了! otherElem
屬於o
,不屬於r
。
將覆蓋文件中的名稱空間改回other
可修復該錯誤,但同樣可以:
問題是為什么是必要的命名空間other
在這里? 同樣令人困惑的是,無論哪種方式, third
層導入都是正確的。
問題已解決,但我們想了解這個概念。 我們缺少什么?
編輯:
為了完整起見,這是我pom.xml
的build
部分:
<build>
<plugins>
<plugin>
<!-- run xjc -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<executions>
<execution>
<id>xjc-generate_classes</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<packageName>test.jaxb.generated</packageName>
<schemaFiles>
root.xsd
</schemaFiles>
<schemaDirectory>${basedir}/src/main/resources/schemata</schemaDirectory>
<extension>true</extension>
<bindingDirectory>${basedir}/src/main/resources/bindings</bindingDirectory>
<outputDirectory>${basedir}/target/generated-sources/jaxb/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<!-- overwrite created package-info.java -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<overwrite>true</overwrite>
<outputDirectory>${basedir}/target/generated-sources/jaxb/test/jaxb/generated</outputDirectory>
<resources>
<resource>
<directory>${basedir}/src/main/resources/bindings</directory>
<include>package-info.java</include>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
問題是您在一個包中生成了所有類(使用Maven插件的packageName
配置)。
不要這樣做。
JAXB在某種程度上基於包命名空間對應的概念。 每個使用的名稱空間應有一個軟件包。 盡管從技術上講可以做到這一點,但您將面臨一個接一個的問題。 因此,最好遵循此概念並為每個名稱空間使用或生成一個包。 您仍然可以配置目標軟件包-但使用綁定文件而不是插件配置元素。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.