我有一个 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>
我不明白为什么我在后代中得到空的命名空间属性。任何人有任何想法???
最佳答案
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
下的元素从他们的父级继承他们的命名空间。
关于xml - 使用 XSLT 向 SOAP XML 消息添加多个命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14699279/