如何使用 XSLT 重命名标签
How to rename a tag using XSLT
我正在尝试使用 WSO2 ESB 模板中的 XSLT 重命名标签。
我所有的尝试都得到了同样的错误:无法使用 XSLT 结果创建 OMElement。
我尝试过的变体之一是:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
<xsl:param name="response_tag"/>
<xsl:template match="RESPONSE">
<xsl:element name="{$response_tag}" >
<xsl:for-each select="/RESPONSE/*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
另一个是:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="request_tag"/>
<xsl:template match="RESPONSE">
<xsl:element name="{$request_tag}">
<xsl:apply-templates select="node() | @*" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
我做错了什么?
PS。参数response_tag
值类似于rns:NameOfResponse
命名空间 (rns
) 和 NameOfResponse
每次都可能不同。命名空间位于 xml 的信封标记内,因此最后(如果转换有效),xml 将有效。
输入类似于:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:rns="http://www.example.com/example">
<soapenv:Header/>
<soapenv:Body>
<RESPONSE xmlns="http://ws.apache.org/ns/synapse">
<tag>123</tag>
<another_tag>20160622134457473</another_tag>
...
</RESPONSE>
</soapenv:Body>
</soapenv:Envelope>
结果应该是:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:rns="http://www.example.com/example">
<soapenv:Header/>
<soapenv:Body>
<rns:NameOfResponse>
<tag>123</tag>
<another_tag>20160622134457473</another_tag>
...
</rns:NameOfResponse>
</soapenv:Body>
</soapenv:Envelope>
PPS。尝试从响应标记中删除名称空间 - 即响应标记现在看起来像:NameOfTag
。同样的错误。
发送此负载:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<RESPONSE>
<tag>123</tag>
<another_tag>20160622134457473</another_tag>
</RESPONSE>
</soapenv:Body>
</soapenv:Envelope>
至此代理:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="TestSOF" transports="http" statistics="disable" trace="disable" startOnLoad="true">
<target>
<inSequence>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
<property name="RequestTagNamespace" value="http://wso2.com"/>
<property name="RequestTagName" value="NameOfResponse"/>
<xslt key="SOFXSL">
<property name="request_tag_namespace" expression="get-property('RequestTagNamespace')"/>
<property name="request_tag" expression="get-property('RequestTagName')"/>
</xslt>
<log level="full"/>
</inSequence>
</target>
<description/>
</proxy>
在本地条目中使用此 xsl 样式表:
<?xml version="1.0" encoding="UTF-8"?>
<localEntry xmlns="http://ws.apache.org/ns/synapse" key="SOFXSL">
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="yes"/>
<xsl:param name="request_tag_namespace"/>
<xsl:param name="request_tag"/>
<xsl:template match="RESPONSE">
<xsl:element name="myns:{$request_tag}" namespace="{$request_tag_namespace}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="@*|*|comment()">
<xsl:copy>
<xsl:apply-templates select="@*|*|text()|comment()|processing-instruction()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<description/>
</localEntry>
你会得到这样的结果:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<myns:tagname xmlns:myns="http://tagnamespace">
<tag>123</tag>
<another_tag>20160622134457473</another_tag>
</myns:tagname>
</soapenv:Body>
</soapenv:Envelope>
我猜你想做这样的事情:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:syn="http://ws.apache.org/ns/synapse"
xmlns="http://www.example.com/example"
exclude-result-prefixes="syn">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="response_tag"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="syn:RESPONSE">
<xsl:element name="{substring-after($response_tag, ':')}" >
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="syn:*">
<xsl:element name="{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
应用于您的输入示例,带有参数 response_tag='rns:NameOfResponse'
,结果将是:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<NameOfResponse xmlns="http://www.example.com/example">
<tag>123</tag>
<another_tag>20160622134457473</another_tag>
...
</NameOfResponse>
</soapenv:Body>
</soapenv:Envelope>
请注意,NameOfResponse
元素声明了一个 默认命名空间 - 这由其后代继承,与您输入的方式相同。
已添加:
要获得问题中显示的确切输出,您可以执行以下操作:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:syn="http://ws.apache.org/ns/synapse"
exclude-result-prefixes="syn">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="response_tag"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="syn:RESPONSE">
<xsl:element name="{$response_tag}" namespace="http://www.example.com/example">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="syn:*">
<xsl:element name="{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
警告:我对 WSO2 一无所知;这就是它在 XSLT 中的工作方式。
我正在尝试使用 WSO2 ESB 模板中的 XSLT 重命名标签。
我所有的尝试都得到了同样的错误:无法使用 XSLT 结果创建 OMElement。
我尝试过的变体之一是:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
<xsl:param name="response_tag"/>
<xsl:template match="RESPONSE">
<xsl:element name="{$response_tag}" >
<xsl:for-each select="/RESPONSE/*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
另一个是:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="request_tag"/>
<xsl:template match="RESPONSE">
<xsl:element name="{$request_tag}">
<xsl:apply-templates select="node() | @*" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
我做错了什么?
PS。参数response_tag
值类似于rns:NameOfResponse
命名空间 (rns
) 和 NameOfResponse
每次都可能不同。命名空间位于 xml 的信封标记内,因此最后(如果转换有效),xml 将有效。
输入类似于:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:rns="http://www.example.com/example">
<soapenv:Header/>
<soapenv:Body>
<RESPONSE xmlns="http://ws.apache.org/ns/synapse">
<tag>123</tag>
<another_tag>20160622134457473</another_tag>
...
</RESPONSE>
</soapenv:Body>
</soapenv:Envelope>
结果应该是:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:rns="http://www.example.com/example">
<soapenv:Header/>
<soapenv:Body>
<rns:NameOfResponse>
<tag>123</tag>
<another_tag>20160622134457473</another_tag>
...
</rns:NameOfResponse>
</soapenv:Body>
</soapenv:Envelope>
PPS。尝试从响应标记中删除名称空间 - 即响应标记现在看起来像:NameOfTag
。同样的错误。
发送此负载:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<RESPONSE>
<tag>123</tag>
<another_tag>20160622134457473</another_tag>
</RESPONSE>
</soapenv:Body>
</soapenv:Envelope>
至此代理:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="TestSOF" transports="http" statistics="disable" trace="disable" startOnLoad="true">
<target>
<inSequence>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
<property name="RequestTagNamespace" value="http://wso2.com"/>
<property name="RequestTagName" value="NameOfResponse"/>
<xslt key="SOFXSL">
<property name="request_tag_namespace" expression="get-property('RequestTagNamespace')"/>
<property name="request_tag" expression="get-property('RequestTagName')"/>
</xslt>
<log level="full"/>
</inSequence>
</target>
<description/>
</proxy>
在本地条目中使用此 xsl 样式表:
<?xml version="1.0" encoding="UTF-8"?>
<localEntry xmlns="http://ws.apache.org/ns/synapse" key="SOFXSL">
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="yes"/>
<xsl:param name="request_tag_namespace"/>
<xsl:param name="request_tag"/>
<xsl:template match="RESPONSE">
<xsl:element name="myns:{$request_tag}" namespace="{$request_tag_namespace}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="@*|*|comment()">
<xsl:copy>
<xsl:apply-templates select="@*|*|text()|comment()|processing-instruction()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<description/>
</localEntry>
你会得到这样的结果:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<myns:tagname xmlns:myns="http://tagnamespace">
<tag>123</tag>
<another_tag>20160622134457473</another_tag>
</myns:tagname>
</soapenv:Body>
</soapenv:Envelope>
我猜你想做这样的事情:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:syn="http://ws.apache.org/ns/synapse"
xmlns="http://www.example.com/example"
exclude-result-prefixes="syn">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="response_tag"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="syn:RESPONSE">
<xsl:element name="{substring-after($response_tag, ':')}" >
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="syn:*">
<xsl:element name="{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
应用于您的输入示例,带有参数 response_tag='rns:NameOfResponse'
,结果将是:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<NameOfResponse xmlns="http://www.example.com/example">
<tag>123</tag>
<another_tag>20160622134457473</another_tag>
...
</NameOfResponse>
</soapenv:Body>
</soapenv:Envelope>
请注意,NameOfResponse
元素声明了一个 默认命名空间 - 这由其后代继承,与您输入的方式相同。
已添加:
要获得问题中显示的确切输出,您可以执行以下操作:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:syn="http://ws.apache.org/ns/synapse"
exclude-result-prefixes="syn">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="response_tag"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="syn:RESPONSE">
<xsl:element name="{$response_tag}" namespace="http://www.example.com/example">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="syn:*">
<xsl:element name="{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
警告:我对 WSO2 一无所知;这就是它在 XSLT 中的工作方式。