我有一个SOAP请求,我试图使用XSLT进行转换。我想为命令中的每个元素添加命名空间限定符。我需要用户使用两个不同的命名空间。这是我正在尝试转换的XML:
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" >
<soapenv:Header/>
<soapenv:Body>
<PingRq>
<RqUID>1</RqUID>
<RequestContext>
<ClientUserID>1</ClientUserID>
<ClientName>Big Company</ClientName>
<ClientApplication>
<AppName>TestApp</AppName>
<AppVersion>1</AppVersion>
</ClientApplication>
<ClientLangPref>En-US</ClientLangPref>
<ClientDt>Mar-29-2013</ClientDt>
</RequestContext>
</PingRq>
</soapenv:Body>
</soapenv:Envelope
以下是我想将其转换为:
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" >
<soapenv:Header/>
<soapenv:Body>
<PingRq namespace="http://www.ns1.com">
<RqUID namespace="http://www.ns2.com">1</RqUID>
<RequestContext namespace="http://www.ns2.com">
<ClientUserID namespace="http://www.ns2.com">1</ClientUserID>
<ClientName namespace="http://www.ns2.com">Big Company</ClientName>
<ClientApplication namespace="http://www.ns2.com">
<AppName namespace="http://www.ns2.com">TestApp</AppName>
<AppVersion namespace="http://www.ns2.com">1</AppVersion>
</ClientApplication>
<ClientLangPref namespace="http://www.ns2.com">En-US</ClientLangPref>
<ClientDt namespace="http://www.ns2.com">Mar-29-2013</ClientDt>
</RequestContext>
</PingRq>
</soapenv:Body>
</soapenv:Envelope>
这是我的样式表
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select = "@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="PingRq">
<xsl:element name="{local-name()}" namespace="http://www.ns1.com">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="PingRq/*">
<xsl:element name="{local-name()}" namespace="http://www.ns2.com">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
这是我得到的结果。
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Header/>
<soapenv:Body>
<PingRq xmlns="http://www.ns1.com">
<RqUID xmlns="http://www.ns2.com">1</RqUID>
<RequestContext xmlns="http://www.ns2.com">
<ClientUserID xmlns="">1</ClientUserID>
<ClientName xmlns="">Big Company</ClientName>
<ClientApplication xmlns="">
<AppName>TestApp</AppName>
<AppVersion>1</AppVersion>
</ClientApplication>
<ClientLangPref xmlns="">En-US</ClientLangPref>
<ClientDt xmlns="">Mar-29-2013</ClientDt>
</RequestContext>
</PingRq>
</soapenv:Body>
</soapenv:Envelope>
我无法弄清楚为什么我在后代中获取空命名空间属性。任何人有任何想法???
答案 0 :(得分:1)
PingRq/*
xpath仅匹配PingRq
元素的直接子元素。要将其所有后代元素放在某个命名空间中,您可以这样做:
<xsl:template match="PingRq//*">
<xsl:element name="{local-name()}" namespace="http://www.ns2.com">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
请注意,结果不会显示所有后代的名称空间声明:
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Header />
<soapenv:Body>
<PingRq xmlns="http://www.ns1.com">
<RqUID xmlns="http://www.ns2.com">1</RqUID>
<RequestContext xmlns="http://www.ns2.com">
<ClientUserID>1</ClientUserID>
<ClientName>Big Company</ClientName>
<ClientApplication>
<AppName>TestApp</AppName>
<AppVersion>1</AppVersion>
</ClientApplication>
<ClientLangPref>En-US</ClientLangPref>
<ClientDt>Mar-29-2013</ClientDt>
</RequestContext>
</PingRq>
</soapenv:Body>
</soapenv:Envelope>
但这是可以预料到的,因为RequestContext
下的元素是从父节点继承它们的命名空间。