如何使用 camel jaxb 设置 marshalled xml 的命名空间?
How to set the namespace of marshalled xml using camel jaxb?
首先,我正在使用 Camel 2.15 版(在 Fuse 6.2.1 中)创建一些路由。
在我的路线中,我试图从使用 cxf-xjc maven 插件生成的 pojo 创建一个 XML(cxf-xjc 在某处读取了一些 xsd 然后从 xsd,产生了带有jaxb注解的pojos)。
pojo 是 TempProject 和 TempProjects。
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(
name = "",
propOrder = {"ecode", "tempName"}
)
@XmlRootElement(
name = "TempProject"
)
public class TempProject implements Serializable {
@XmlElement(
name = "Ecode",
required = true
)
protected String ecode;
@XmlElement(
name = "TempName",
required = true
)
protected String tempName;
public TempProject() {
}
public String getEcode() {
return this.ecode;
}
public void setEcode(String value) {
this.ecode = value;
}
public String getTempName() {
return this.tempName;
}
public void setTempName(String value) {
this.tempName = value;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(
name = "",
propOrder = {"tempProjects"}
)
@XmlRootElement(
name = "TempProjects"
)
public class TempProjects implements Serializable {
@XmlElement(
name = "TempProject",
required = true
)
protected List<TempProject> tempProjects;
public TempProjects() {
}
public List<TempProject> getTempProjects() {
if (this.tempProjects == null) {
this.tempProjects = new ArrayList();
}
return this.tempProjects;
}
}
我可以使用以下代码生成 xml:
JAXBContext jaxbContext = JAXBContext.newInstance(new Class[]{TempProjects.class});
jaxbContext.createMarshaller();
JaxbDataFormat jaxbDataFormat = new JaxbDataFormat(jaxbContext); //import org.apache.camel.converter.jaxb.JaxbDataFormat;
我打电话
.marshal(jaxbDataFormat)
在我实现从 pojo 到 xml 的编组的路线中。
生成的xml贴在下面:
<TempProjects xmlns="http://blah.blah/foo/schema/v2">
<TempProject>
<Ecode>1</Ecode>
<TempName>Tempname1</TempName>
</TempProject>
<TempProject>
<Ecode>2</Ecode>
<TempName>Tempname2</TempName>
</TempProject>
我如何生成编组的 xml 将具有这样的命名空间...
<TempProjects xmlns:myprefix="http://blah.blah/foo/schema/v2">
我需要命名空间前缀的原因是因为我计划使用 xpath 拆分 xml 中的值(例如 Ecode),我需要一个命名空间前缀来做那(那是我研究过的,我可能是错的)。
我在路线中计划的代码是
.marshal(jaxbDataFormat)
.split( xpath("/TempProjects/TempProject/Ecode/text()").namespaces(ns1),
new ProjectIdsAggregator()) //the above xpath doesn't work because it doesn't have a namespace prefix
//Namespaces ns1 = new Namespaces("myprefix", "http://blah.blah/foo/schema/v2" );
我查看了 jaxbDataFormat.setNamespacePrefixRef("myprefix"),但出现错误 (org.apache.camel.NoSuchBeanException: 在注册表中找不到 bean for: myprefix of输入:java.util.Map)
我实际上是 apache camel 路由世界的新手,所以我可能会遗漏一些基本的东西。
您根本不需要更改 XML。没问题。
使用您发布的 XML 和您发布的命名空间声明,以下 XPath 可以很好地将 XML (作为示例)拆分为两个 TempProject
部分:
xpath("/myprefix:TempProjects/myprefix:TempProject").namespaces(ns1)
因为您这样声明 XML 命名空间:
Namespaces ns1 = new Namespaces("myprefix", "http://blah.blah/foo/schema/v2" )
您的 XPath 必须对所有元素使用前缀 myprefix
:
/myprefix:TempProjects/myprefix:TempProject
首先,我正在使用 Camel 2.15 版(在 Fuse 6.2.1 中)创建一些路由。
在我的路线中,我试图从使用 cxf-xjc maven 插件生成的 pojo 创建一个 XML(cxf-xjc 在某处读取了一些 xsd 然后从 xsd,产生了带有jaxb注解的pojos)。
pojo 是 TempProject 和 TempProjects。
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(
name = "",
propOrder = {"ecode", "tempName"}
)
@XmlRootElement(
name = "TempProject"
)
public class TempProject implements Serializable {
@XmlElement(
name = "Ecode",
required = true
)
protected String ecode;
@XmlElement(
name = "TempName",
required = true
)
protected String tempName;
public TempProject() {
}
public String getEcode() {
return this.ecode;
}
public void setEcode(String value) {
this.ecode = value;
}
public String getTempName() {
return this.tempName;
}
public void setTempName(String value) {
this.tempName = value;
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(
name = "",
propOrder = {"tempProjects"}
)
@XmlRootElement(
name = "TempProjects"
)
public class TempProjects implements Serializable {
@XmlElement(
name = "TempProject",
required = true
)
protected List<TempProject> tempProjects;
public TempProjects() {
}
public List<TempProject> getTempProjects() {
if (this.tempProjects == null) {
this.tempProjects = new ArrayList();
}
return this.tempProjects;
}
}
我可以使用以下代码生成 xml:
JAXBContext jaxbContext = JAXBContext.newInstance(new Class[]{TempProjects.class});
jaxbContext.createMarshaller();
JaxbDataFormat jaxbDataFormat = new JaxbDataFormat(jaxbContext); //import org.apache.camel.converter.jaxb.JaxbDataFormat;
我打电话
.marshal(jaxbDataFormat)
在我实现从 pojo 到 xml 的编组的路线中。
生成的xml贴在下面:
<TempProjects xmlns="http://blah.blah/foo/schema/v2">
<TempProject>
<Ecode>1</Ecode>
<TempName>Tempname1</TempName>
</TempProject>
<TempProject>
<Ecode>2</Ecode>
<TempName>Tempname2</TempName>
</TempProject>
我如何生成编组的 xml 将具有这样的命名空间...
<TempProjects xmlns:myprefix="http://blah.blah/foo/schema/v2">
我需要命名空间前缀的原因是因为我计划使用 xpath 拆分 xml 中的值(例如 Ecode),我需要一个命名空间前缀来做那(那是我研究过的,我可能是错的)。
我在路线中计划的代码是
.marshal(jaxbDataFormat)
.split( xpath("/TempProjects/TempProject/Ecode/text()").namespaces(ns1),
new ProjectIdsAggregator()) //the above xpath doesn't work because it doesn't have a namespace prefix
//Namespaces ns1 = new Namespaces("myprefix", "http://blah.blah/foo/schema/v2" );
我查看了 jaxbDataFormat.setNamespacePrefixRef("myprefix"),但出现错误 (org.apache.camel.NoSuchBeanException: 在注册表中找不到 bean for: myprefix of输入:java.util.Map)
我实际上是 apache camel 路由世界的新手,所以我可能会遗漏一些基本的东西。
您根本不需要更改 XML。没问题。
使用您发布的 XML 和您发布的命名空间声明,以下 XPath 可以很好地将 XML (作为示例)拆分为两个 TempProject
部分:
xpath("/myprefix:TempProjects/myprefix:TempProject").namespaces(ns1)
因为您这样声明 XML 命名空间:
Namespaces ns1 = new Namespaces("myprefix", "http://blah.blah/foo/schema/v2" )
您的 XPath 必须对所有元素使用前缀 myprefix
:
/myprefix:TempProjects/myprefix:TempProject