【问题标题】:How to set the namespace of marshalled xml using camel jaxb?如何使用camel jaxb设置编组xml的命名空间?
【发布时间】:2019-02-17 00:51:40
【问题描述】:

对于初学者,我正在使用 Camel 2.15 版(在 Fuse 6.2.1 中)创建一些路线。

在我的路线中,我正在尝试从使用 cxf-xjc maven 插件生成的 pojo 创建 XML(cxf-xjc 在某处读取了一些 xsd,然后从 xsd 中读取了带有 jaxb 注释的 pojo)。

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: No bean can be found in the registry for: myprefix of type: java.util.地图)

我实际上是 apache 骆驼路由领域的新手,所以我可能会遗漏一些基本的东西。

【问题讨论】:

  • 您的 xpath 可以在没有 .namespaces(ns1) 的情况下使用默认 xml。在没有命名空间的情况下运行路由时你有什么问题吗?
  • @c0ld 它不起作用,我仍然可以在 split() 之后在日志中看到整个 xml... split[XPath: /TempProjects/TempProject/Ecode/text()] -->停止 blah.blah/foo/schema/v2"> 1Tempname12Tempname2跨度>
  • 漫不经心地阅读 =) 关于 jaxb 的答案你在这里找不到 stackoverflow.com/questions/6895486/… 但更好的方法是由 @burki 回答

标签: jaxb apache-camel jbossfuse


【解决方案1】:

您根本不需要更改您的 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 

【讨论】:

    猜你喜欢
    • 2018-03-27
    • 1970-01-01
    • 1970-01-01
    • 2014-11-28
    • 1970-01-01
    • 2012-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多