Java 如何检测SOAP消息中是否存在命名空间前缀

Java 如何检测SOAP消息中是否存在命名空间前缀,java,xpath,soap,Java,Xpath,Soap,我正在开发一个java应用程序,它接受来自许多不同远程客户端的SOAP/HTTPWeb服务请求 我无法控制这些客户端以及它们如何构造SOAP请求 我必须从这些SOAP请求消息中提取多个关键XML元素及其相关数据 一些客户端在所有标记上使用名称空间前缀,而其他客户端则不使用 是否有任何方法可以检测我收到的每个SOAP请求消息(或子文档)中是否存在名称空间前缀?正如其他人已经评论的那样,名称空间前缀并不重要: 在具有名称空间的XML中,元素或属性名称是限定名称,即它们由名称空间和本地名称部分组成,名

我正在开发一个java应用程序,它接受来自许多不同远程客户端的SOAP/HTTPWeb服务请求

我无法控制这些客户端以及它们如何构造SOAP请求

我必须从这些SOAP请求消息中提取多个关键XML元素及其相关数据

一些客户端在所有标记上使用名称空间前缀,而其他客户端则不使用


是否有任何方法可以检测我收到的每个SOAP请求消息(或子文档)中是否存在名称空间前缀?

正如其他人已经评论的那样,名称空间前缀并不重要:

在具有名称空间的XML中,元素或属性名称是限定名称,即它们由名称空间和本地名称部分组成,名称空间由前缀标识,由冒号与本地名称分隔。如果前缀为空,则不存在冒号,并且名称被称为位于默认命名空间中;如果前缀为非空,则名称根据其作用域内命名空间绑定(类似于以
xmlns
开头的声明的属性)被称为位于命名空间中

前缀本身与名称的标识无关。名称空间和本地部分很重要。以下所有示例对于
信封
具有相同的限定名称,尽管它们的前缀不同:

<root>
  <envelope xmlns="urn:envelopes" />
</root>

<root xmlns:env="urn:envelopes">
  <env:envelope/>
</root>

<root xmlns:soap="urn:envelopes">
  <soap:envelope xmlns="urn:envelopes" />
</root>

<root xmlns:soap="urn:envelopes">
  <envelope xmlns="urn:envelopes" />
</root>

<root xmlns:soap="urn:envelopes">
  <foobar:envelope xmlns:foobar="urn:envelopes" />
</root>
虽然这将回答您的问题,但名称空间重新声明将导致返回一个前缀,该前缀实际上绑定到多个名称空间。要获取所有唯一名称,即前缀+冒号+本地名称,可以使用:

不同的值((/*|@*)/name()
使用XPath 1.0获得相同的信息有点夸张,因为没有
不同的值
,路径表达式的右侧不能返回非节点项。相反,我建议使用一点XSLT1.0,这很容易用Java实现(或者,选择所有节点并使用普通Java对其进行迭代):


@

;
或者,如果您确实只需要前缀,则会转储带有前缀的名称和关联的名称空间:

<xsl:template match="*[contains(name(), ':')] | @*[contains(name(), ':')]">
    <xsl:if test="not(self::*)">@</xsl:if>
    <xsl:value-of select="concat(name(), ' uses &quot;', namespace-uri(), '&quot;')" />
    <xsl:text>&#xA;</xsl:text>
    <xsl:apply-templates select="* | @*" />
</xsl:template>

<xsl:template match="*" ><xsl:apply-templates select="* | @*"/></xsl:template>

<xsl:template match="text() | @*" />

@

;

事实上,只要文件有效,就无所谓了。请举例说明您需要接受的文件类型。每行的前几行应该足够了。通常,名称空间前缀并不重要,但所有SOAP请求都必须位于SOAP标准指定的名称空间中。因此,同样可以忽略前缀,只在正确的名称空间中查找元素。
<xsl:template match="*[contains(name(), ':')] | @*[contains(name(), ':')]">
    <xsl:if test="not(self::*)">@</xsl:if>
    <xsl:value-of select="concat(name(), ' uses &quot;', namespace-uri(), '&quot;')" />
    <xsl:text>&#xA;</xsl:text>
    <xsl:apply-templates select="* | @*" />
</xsl:template>

<xsl:template match="*" ><xsl:apply-templates select="* | @*"/></xsl:template>

<xsl:template match="text() | @*" />