[英]Remove xmlns soap attribute from xml using xslt
I am trying to Copying soap message to custom xml(removing soap namespace from Envelope, Header,Body and removing namespace prefix from ResponseHeader element, everything fine expect one xmlns:soap namespace coming in ResponseHeader and ResponseData elements. 我试图将soap消息复制到自定义xml(从Envelope,Header,Body中删除soap命名空间并从ResponseHeader元素中删除命名空间前缀,一切都很好,期望一个xmlns:soap命名空间来自ResponseHeader和ResponseData元素。
Input: 输入:
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns="http:test/201/2"
xmlns:m0="http:test/201/3"
xmlns:ns0="http:test/201/4"
xmlns:ns2="http:test/201/5"
xmlns:ns1="http:test/201/6"
xmlns:ns3="http:test/201/7"
xmlns:ns6="http:test/201/8"
xmlns:ns4="http:test/201/9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>
<soap:Header>
<ns0:ResponseHeader>
<ns:Env>Dev</ns:Env>
<ns:Version>1</ns:Version>
<ns:Server>
<ns:Name>NAME</ns:Name>
</ns0:ResponseHeader>
</soap:Header>
<soap:Body>
<ns2:ResponseData>
<ns2:Employee />
<ns2:MessageList>
<ns2:Message>
<ns4:Type>new</ns4:Type>
<ns4:Code>1</ns4:Code>
<ns4:Source>contract</ns4:Source>
<ns4:Description>new hire</ns4:Description>
</ns2:Message>
</ns2:Employee>
</ns2:ResponseData>
</soap:Body>
</soap:Envelope>
Expected Output: 预期产出:
<Envelope
xmlns:ns="http:test/201/2"
xmlns:m0="http:test/201/3"
xmlns:ns0="http:test/201/4"
xmlns:ns2="http:test/201/5"
xmlns:ns1="http:test/201/6"
xmlns:ns3="http:test/201/7"
xmlns:ns6="http:test/201/8"
xmlns:ns4="http:test/201/9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>
<Header>
<ResponseHeader>
<ns:Env>Dev</ns:Env>
<ns:Version>1</ns:Version>
<ns:Server>
<ns:Name>NAME</ns:Name>
</ResponseHeader>
</Header>
<Body>
<ns2:ResponseData>
<ns2:Employee />
<ns2:MessageList>
<ns2:Message>
<ns4:Type>new</ns4:Type>
<ns4:Code>1</ns4:Code>
<ns4:Source>contract</ns4:Source>
<ns4:Description>new hire</ns4:Description>
</ns2:Message>
</ns2:Employee>
</ns2:ResponseData>
</Body>
</Envelope>
My Xslt: 我的Xslt:
<xsl:stylesheet version="2.0" extension-element-prefixes="dp" exclude-result-prefixes="soap ns3 snss ns0 ns1 ns4 #default"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns="http:test/201/2"
xmlns:m0="http:test/201/3"
xmlns:ns0="http:test/201/4"
xmlns:ns2="http:test/201/5"
xmlns:ns1="http:test/201/6"
xmlns:ns3="http:test/201/7"
xmlns:ns6="http:test/201/8"
xmlns:ns4="http:test/201/9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>
<xsl:output method="xml" version="1.0" indent="no"/>
<xsl:template match="node()|@*" exclude-result-prefixes="#all">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="soap:*" exclude-result-prefixes="#all">
<xsl:element name="{local-name()}">
<xsl:copy-of select="namespace::*[not(. = namespace-uri(..))]"/>
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
<xsl:template match="tns:ResponseData" exclude-result-prefixes="#all">
<ResponseHeader>
<xsl:copy-of select="namespace::*[not(. = namespace-uri(..))]"/>
<xsl:apply-templates select="node()|@*"/>
</ResponseHeader>
</xsl:template>
</xsl:stylesheet>
Getting output: 获得输出:
<Envelope
xmlns:ns="http:test/201/2"
xmlns:m0="http:test/201/3"
xmlns:ns0="http:test/201/4"
xmlns:ns2="http:test/201/5"
xmlns:ns1="http:test/201/6"
xmlns:ns3="http:test/201/7"
xmlns:ns6="http:test/201/8"
xmlns:ns4="http:test/201/9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>
<Header>
<ResponseHeader xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<ns:Env>Dev</ns:Env>
<ns:Version>1</ns:Version>
<ns:Server>
<ns:Name>NAME</ns:Name>
</ResponseHeader>
</Header>
<Body>
<ns2:ResponseData xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<ns2:Employee />
<ns2:MessageList>
<ns2:Message>
<ns4:Type>new</ns4:Type>
<ns4:Code>1</ns4:Code>
<ns4:Source>contract</ns4:Source>
<ns4:Description>new hire</ns4:Description>
</ns2:Message>
</ns2:Employee>
</ns2:ResponseData>
</Body>
</Envelope>
Please help how to get rid if xmlns:soap attribute? 请帮助如何摆脱xmlns:soap属性?
Neither your input nor your output is a well-formed XML. 您的输入和输出都不是格式良好的XML。 And your "XSLT" is not even an XSLT document! 而你的“XSLT”甚至不是XSLT文档!
AFAICT, you want to do: AFAICT,你想做:
XSLT 2.0 XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns0="http:test/201/4"
exclude-result-prefixes="soap">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="soap:* | ns0:ResponseHeader">
<xsl:element name="{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="/soap:Envelope">
<Envelope>
<xsl:copy-of select="namespace::*"/>
<xsl:apply-templates/>
</Envelope>
</xsl:template>
</xsl:stylesheet>
Applying this to the following well-formed XML input: 将此应用于以下格式良好的XML输入:
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns="http:test/201/2"
xmlns:m0="http:test/201/3"
xmlns:ns0="http:test/201/4"
xmlns:ns2="http:test/201/5"
xmlns:ns1="http:test/201/6"
xmlns:ns3="http:test/201/7"
xmlns:ns6="http:test/201/8"
xmlns:ns4="http:test/201/9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Header>
<ns0:ResponseHeader>
<ns:Env>Dev</ns:Env>
<ns:Version>1</ns:Version>
<ns:Server/>
<ns:Name>NAME</ns:Name>
</ns0:ResponseHeader>
</soap:Header>
<soap:Body>
<ns2:ResponseData>
<ns2:Employee>
<ns2:MessageList>
<ns2:Message>
<ns4:Type>new</ns4:Type>
<ns4:Code>1</ns4:Code>
<ns4:Source>contract</ns4:Source>
<ns4:Description>new hire</ns4:Description>
</ns2:Message>
</ns2:MessageList>
</ns2:Employee>
</ns2:ResponseData>
</soap:Body>
</soap:Envelope>
will return: 将返回:
<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns:ns0="http:test/201/4" xmlns:ns="http:test/201/2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:m0="http:test/201/3"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns2="http:test/201/5"
xmlns:ns1="http:test/201/6"
xmlns:ns3="http:test/201/7"
xmlns:ns6="http:test/201/8"
xmlns:ns4="http:test/201/9">
<Header>
<ResponseHeader>
<ns:Env>Dev</ns:Env>
<ns:Version>1</ns:Version>
<ns:Server/>
<ns:Name>NAME</ns:Name>
</ResponseHeader>
</Header>
<Body>
<ns2:ResponseData>
<ns2:Employee>
<ns2:MessageList>
<ns2:Message>
<ns4:Type>new</ns4:Type>
<ns4:Code>1</ns4:Code>
<ns4:Source>contract</ns4:Source>
<ns4:Description>new hire</ns4:Description>
</ns2:Message>
</ns2:MessageList>
</ns2:Employee>
</ns2:ResponseData>
</Body>
</Envelope>
Note that the last template matching /soap:Envelope
is included for purely cosmetic reasons. 请注意,最后一个模板匹配/soap:Envelope
是出于纯粹的美观原因。 If you remove it, the result will be: 如果删除它,结果将是:
<?xml version="1.0" encoding="UTF-8"?>
<Envelope>
<Header>
<ResponseHeader>
<ns:Env xmlns:ns="http:test/201/2">Dev</ns:Env>
<ns:Version xmlns:ns="http:test/201/2">1</ns:Version>
<ns:Server xmlns:ns="http:test/201/2"/>
<ns:Name xmlns:ns="http:test/201/2">NAME</ns:Name>
</ResponseHeader>
</Header>
<Body>
<ns2:ResponseData xmlns:ns2="http:test/201/5">
<ns2:Employee>
<ns2:MessageList>
<ns2:Message>
<ns4:Type xmlns:ns4="http:test/201/9">new</ns4:Type>
<ns4:Code xmlns:ns4="http:test/201/9">1</ns4:Code>
<ns4:Source xmlns:ns4="http:test/201/9">contract</ns4:Source>
<ns4:Description xmlns:ns4="http:test/201/9">new hire</ns4:Description>
</ns2:Message>
</ns2:MessageList>
</ns2:Employee>
</ns2:ResponseData>
</Body>
</Envelope>
which is semantically identical to the previous result. 这在语义上与先前的结果相同。
This solution works in all versions of XSLT: 1.0, 2.0 and 3.0 (and is also much shorter): 此解决方案适用于所有版本的XSLT:1.0,2.0和3.0 (也更短):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:x="http:test/201/4">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="*" priority="1">
<xsl:element name="{name()}" namespace="{namespace-uri()}">
<xsl:copy-of select="namespace::*[not(name()='soap')]"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="soap:* | x:ResponseHeader" priority="2">
<xsl:element name="{local-name()}">
<xsl:copy-of select="namespace::*[not(name()='soap')]"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the XML document (well-formed): 当此转换应用于XML文档 (格式良好)时:
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns="http:test/201/2"
xmlns:m0="http:test/201/3"
xmlns:ns0="http:test/201/4"
xmlns:ns2="http:test/201/5"
xmlns:ns1="http:test/201/6"
xmlns:ns3="http:test/201/7"
xmlns:ns6="http:test/201/8"
xmlns:ns4="http:test/201/9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Header>
<ns0:ResponseHeader>
<ns:Env>Dev</ns:Env>
<ns:Version>1</ns:Version>
<ns:Server/>
<ns:Name>NAME</ns:Name>
</ns0:ResponseHeader>
</soap:Header>
<soap:Body>
<ns2:ResponseData>
<ns2:Employee>
<ns2:MessageList>
<ns2:Message>
<ns4:Type>new</ns4:Type>
<ns4:Code>1</ns4:Code>
<ns4:Source>contract</ns4:Source>
<ns4:Description>new hire</ns4:Description>
</ns2:Message>
</ns2:MessageList>
</ns2:Employee>
</ns2:ResponseData>
</soap:Body>
</soap:Envelope>
the wanted, correct result is produced : 产生了想要的正确结果 :
<Envelope xmlns:ns="http:test/201/2" xmlns:m0="http:test/201/3"
xmlns:ns0="http:test/201/4" xmlns:ns2="http:test/201/5"
xmlns:ns1="http:test/201/6" xmlns:ns3="http:test/201/7"
xmlns:ns6="http:test/201/8" xmlns:ns4="http:test/201/9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Header>
<ResponseHeader>
<ns:Env>Dev</ns:Env>
<ns:Version>1</ns:Version>
<ns:Server/>
<ns:Name>NAME</ns:Name>
</ResponseHeader>
</Header>
<Body>
<ns2:ResponseData>
<ns2:Employee>
<ns2:MessageList>
<ns2:Message>
<ns4:Type>new</ns4:Type>
<ns4:Code>1</ns4:Code>
<ns4:Source>contract</ns4:Source>
<ns4:Description>new hire</ns4:Description>
</ns2:Message>
</ns2:MessageList>
</ns2:Employee>
</ns2:ResponseData>
</Body>
</Envelope>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.