JAXB编组XML的部分,并保持原始名称前缀
我正在使用以下插件来生成JAXB类。然后,我从文件系统中阅读了一些XML,然后将其删除为生成的JAXB类。这些课程包含我需要单独拆卸的条目的集合,进行一些业务逻辑,并为每个部分取消分组,并将其存储为XML零件。因此,实际上我正在做XML->对象(进行一些业务逻辑) - >我存储在某个地方的较小的XML。问题是,文件系统中的XML具有正确的名称空间前缀(例如TCA,TCB,TCC),并且在将这些较小的部分编码回XML时,JAXB创建了自己的名称空间前缀,例如NS1,NS2,NS3,NS3。是否可以像原始文件一样具有TCA,TCB,TCC?但是也许不是要定义自己的前缀映射,因为我永远不知道我的文件系统会出现哪些前缀。一些外部聚会将来可能会改变它们,我只想保留原始聚会。 Belo是我的代码。
代码生成插件:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>${jaxb2-maven-plugin.version}</version>
<executions>
<execution>
<id>xjc</id>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<sources>
<source>src/main/resources/my.xsd</source>
</sources>
<outputDirectory>${basedir}/target/generated-sources/java</outputDirectory>
<clearOutputDir>false</clearOutputDir>
</configuration>
</plugin>
代码
JAXBContext jaxbContext = JAXBContext.newInstance(MyRoot.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
while (streamReader.hasNext()) {
if (streamReader.isStartElement()) {
if (streamReader.getName() != null && streamReader.getName().getLocalPart() != null) {
String localPart = streamReader.getName().getLocalPart();
if (localPart.equalsIgnoreCase(XmlElements.CAR)) {
JAXBElement<Car> carJAXBElement = unmarshaller.unmarshal(streamReader, Car.class);
//doing some business logic
JAXBContext context = JAXBContext.newInstance(Car.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
StringWriter sw = new StringWriter();
m.marshal(carJAXBElement, sw);
String result = sw.toString(); //the result has namespaces prefixes changed
//and then saving one car xml part somewhere
}
}
}
streamReader.next();
XML文件
原始文件:
<?xml version="1.0" encoding="UTF-8"?>
<tca:myroot xmlns:tca="http://myspec/tca/1.0" >
<tca:car>
<tca:owner>
<tca:name>
</tca:name>
</tca:owner>
</tca:car>
<tca:car>
<tca:owner>
<tca:name>
</tca:name>
</tca:owner>
</tca:car>
</tca:myroot>
chandered car xml part:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns4:car xmlns:ns4="http://myspec/tca/1.0" >
<ns4:owner>
<ns4:name>
</ns4:name>
</ns4:owner>
</ns4:car>
编组后,是否可以在那些小型汽车零件中有原始名称空间前缀?
I am using below plugin to generate jaxb classes. I then read some XML from filesystem and unmarshall it to generated jaxb classes. Those classes has collection of entries that I need to unmarshall separately, do some business logic and for each part unmarshalled and store them as xml parts. So in fact I am doing XML -> Object (to do some business logic) -> smaller XMLs which I am storing somewhere. Problem is that the XML in filesystem has correct namespaces prefixes (like tca, tcb, tcc) and while marshalling those smaller parts back to xml, jaxb creates its own namespaces prefixes like ns1, ns2, ns3. Is it possible to have tca, tcb, tcc as in original file ? But maybe not to define my own prefixes map because I never know what prefixes will come to my filesystem. Some external party may change them in future and I only want to keep original ones. Belo is my code.
Code generation plugin:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>${jaxb2-maven-plugin.version}</version>
<executions>
<execution>
<id>xjc</id>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<sources>
<source>src/main/resources/my.xsd</source>
</sources>
<outputDirectory>${basedir}/target/generated-sources/java</outputDirectory>
<clearOutputDir>false</clearOutputDir>
</configuration>
</plugin>
The code
JAXBContext jaxbContext = JAXBContext.newInstance(MyRoot.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
while (streamReader.hasNext()) {
if (streamReader.isStartElement()) {
if (streamReader.getName() != null && streamReader.getName().getLocalPart() != null) {
String localPart = streamReader.getName().getLocalPart();
if (localPart.equalsIgnoreCase(XmlElements.CAR)) {
JAXBElement<Car> carJAXBElement = unmarshaller.unmarshal(streamReader, Car.class);
//doing some business logic
JAXBContext context = JAXBContext.newInstance(Car.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
StringWriter sw = new StringWriter();
m.marshal(carJAXBElement, sw);
String result = sw.toString(); //the result has namespaces prefixes changed
//and then saving one car xml part somewhere
}
}
}
streamReader.next();
The xml files
Original file:
<?xml version="1.0" encoding="UTF-8"?>
<tca:myroot xmlns:tca="http://myspec/tca/1.0" >
<tca:car>
<tca:owner>
<tca:name>
</tca:name>
</tca:owner>
</tca:car>
<tca:car>
<tca:owner>
<tca:name>
</tca:name>
</tca:owner>
</tca:car>
</tca:myroot>
Marshalled car xml part:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns4:car xmlns:ns4="http://myspec/tca/1.0" >
<ns4:owner>
<ns4:name>
</ns4:name>
</ns4:owner>
</ns4:car>
Is it possible to have original namespaces prefixes in those small car parts after marshalling them?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
因此,尽管没有答案,但我还是自己想知道。因此,我正在为将来的搜索者添加信息 - 如果您发现它有用,请标记我的答案是有效的,因为我不想自己做。
我使用了spaceprefixmapper,其中有映射前缀 - &gt;每个名称空间的名称空间URI从其第一个元素中读取XML文件中的命名空间。它运行良好,但是Sonar抱怨我正在使用Sun Internallass:
因此我使用了package-info.java方法。我注意到,
jaxb2-maven-plugin
xjc
目标创建默认的软件包info.java。在此文件中,可以将自己的名称空间前缀添加到名称空间URI映射中。然后,我使用Maven-Resources-Plugin
将我自己的Package-info.java复制到生成类的包装。最后,当邮政使用者将对象转换回XML文件时,它使用我的Package-info.java和原始名称空间前缀而不是NS1,NS2,等。So despite there were no answers, I've figured it out by myself.. So I am adding info for future searchers - please mark my answer as valid if u will find it useful because I don't want to do it by myself.
I used NamespacePrefixMapper where I had mapping prefix -> namespace uri for each namespace read in xml file from its first element. It worked fine, but Sonar was complaining that I am using sun internal classes:
So I then used package-info.java approach. I noticed, that
jaxb2-maven-plugin
xjc
goal creates default package-info.java. Inside this file it is possible to add your own namespace prefix to namespace uri mapping. Then I usedmaven-resources-plugin
to copy my own package-info.java to package of generated classes. Finally when marshaller is converting objects back to xml files, it uses my package-info.java and original namespace prefixes are preserved instead of ns1, ns2, etc.