我有一个Apache camel应用程序,它与web服务对话。我需要将响应soap消息转换/解封送到代理对象中。我没有使用soap数据格式,而是使用jaxb转换,为此我需要首先从soap消息中提取xml。当我从命令行运行应用程序时,下面的xsl和soap响应可以正常工作,但是如果我将应用程序部署在JBoss eap 6.2 GA上,则会失败。我的xsl、示例响应soap消息和生成的xml如下所示:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
version="1.0">
<xsl:output method="xml" indent="no" />
<xsl:strip-space elements="*" />
<xsl:template match="/*">
<xsl:copy-of select="/soapenv:Envelope/soapenv:Body/*" />
</xsl:template>
<xsl:template match="/*">
<xsl:copy-of select="/s:Envelope/s:Body/*" />
</xsl:template>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
示例soap消息是:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<ActivityId CorrelationId="8877bd15-990e-465f-acca-3b2f21945735"
xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">b0480ae4-7692-4224-9082-662cbe8a6edc</ActivityId>
</s:Header>
<s:Body>
<GetUserByEmailResponse xmlns="urn:RetailApi/AccountManagementService/v2">
<GetUserByEmailResult xmlns:a="urn:RetailApi/Schemas/v2"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:EmailAddress>a@b.com</a:EmailAddress>
<a:FirstName>Scott</a:FirstName>
<a:LastName>Tiger</a:LastName>
<a:MobilePhoneNumber>3232326565</a:MobilePhoneNumber>
<a:Title>Mr</a:Title>
<a:UserId>xxxxx</a:UserId>
</GetUserByEmailResult>
</GetUserByEmailResponse>
</s:Body>
生成的xml是:
<?xml version="1.0" encoding="UTF-8"?>< xmlns="urn:RetailApi/AccountManagementService/v2"><><a:EmailAddress xmlns:a="urn:RetailApi/Schemas/v2">a@b.com</a:EmailAddress><a:FirstName xmlns:a="urn:RetailApi/Schemas/v2">Scott</a:FirstName><a:LastName xmlns:a="urn:RetailApi/Schemas/v2">Tiger</a:LastName><a:MobilePhoneNumber xmlns:a="urn:RetailApi/Schemas/v2">3232326565</a:MobilePhoneNumber><a:Title xmlns:a="urn:RetailApi/Schemas/v2">Mr</a:Title><a:UserId xmlns:a="urn:RetailApi/Schemas/v2">xxxx</a:UserId></></>
如您所见,生成的xml有几个问题。com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character ' ' (code 32) in prolog, after '<'.
这个问题只发生在我通过应用服务器运行我的应用程序时,当我作为一个独立的应用程序运行时不会发生。
并没有真正回答为什么XSLT只在运行JBoss时生成验证的空格。
但是,解决您的用例的另一种方法是简单的xpath,根本不涉及XSLT。
final Namespaces ns = new Namespaces("soap", "http://schemas.xmlsoap.org/soap/envelope/");
from("foo:bar")
.setBody(ns.xpath("/soap:Envelope/soap:Body/*[1]",String.class)
// do whatever
如果您考虑使用这些组件,SpringWS和CXF也可以自动处理这些内容。
经过大量的挖掘/调试,我投降了,选择了直接但不那么干净的解决方案。我编写了一个实用程序方法来使用字符串API提取xml。这招很管用。