在 XML 中转义反斜杠并使用 XSLT 拆分为单独的 xml 节点 [英] Escape backslash in XML and split as separate xml node using XSLT
问题描述
我正在寻找一些帮助以使用 XSLT 将以下格式的 XML 转换为所需的输出 -
I am looking for some help to convert the following format XML using XSLT to the desired output -
输入 XML:
<properties>
<entry>
<key>first_node</key>
<value>GDP</value>
</entry>
<entry>
<key>parent_node/second_node/third_node</key>
<value>INR</value>
</entry>
<entry>
<key>fourth_node</key>
<value>
<genericData>
<identifier>fourth_node</identifier>
<properties>
<entry>
<key>fifth_node/sixth_node</key>
<value>USD</value>
</entry>
<entry>
<key>seventh_node</key>
<value>EUR</value>
</entry>
</properties>
</genericData>
</value>
</entry>
<entry>
<key>eigth_node</key>
<value>
<genericData>
<identifier>eigth_node</identifier>
<properties>
<entry>
<key>ninth_node</key>
<value>SGD</value>
</entry>
<entry>
<key>tenth_node</key>
<value>PSO</value>
</entry>
</properties>
</genericData>
</value>
</entry>
</properties>
期望的输出:
<properties>
<first_node>GDP</first_node>
<parent_node>
<second_node>
<third_node>INR</third_node>
</second_node>
</parent_node>
<fourth_node>
<fifth_node>
<sixth_node>USD</sixth_node>
</fifth_node>
<seventh_node>EUR</seventh_node>
</fourth_node>
<eight_node>
<ninth_node>SGD</ninth_node>
<tenth_node>PSO</tenth_node>
</eight_node>
</properties>
我用一个可能的输入 XML 修改了问题,其中格式稍有变化.
I have modified the question with a possible input XML where the format is changed a bit.
请帮助使用 XSLT 版本 1 以获得所需的输出.
Kindly help with the XSLT Version 1 to get the desired output.
非常感谢您的帮助.
推荐答案
在 XSLT 2 或 3 中,您可以使用 XPath tokenize
函数来构造具有递归模板中元素名称的字符串序列根据需要构造嵌套元素:
In XSLT 2 or 3 you can use the XPath tokenize
function to construct a sequence of strings with the element names in a recursive template constructing the nested elements as needed:
<xsl:template match="entry">
<xsl:param name="element-names" as="xs:string*" select="tokenize(string[1], '/')"/>
<xsl:variable name="element-name" as="xs:string?" select="head($element-names)"/>
<xsl:choose>
<xsl:when test="$element-name">
<xsl:element name="{$element-name}">
<xsl:apply-templates select=".">
<xsl:with-param name="element-names" select="tail($element-names)"/>
</xsl:apply-templates>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="string[2]"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
完整的 XSLT 3 样式表将是
Full XSLT 3 stylesheet would be
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="entry">
<xsl:param name="element-names" as="xs:string*" select="tokenize(string[1], '/')"/>
<xsl:variable name="element-name" as="xs:string?" select="head($element-names)"/>
<xsl:choose>
<xsl:when test="$element-name">
<xsl:element name="{$element-name}">
<xsl:apply-templates select=".">
<xsl:with-param name="element-names" select="tail($element-names)"/>
</xsl:apply-templates>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="string[2]"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/3NzcBtK 中的示例,对于XSLT 2 你需要说明身份转换,我认为你需要使用 element-names[1]
而不是使用 head($element-names)
和而不是对该变量的 tail
调用,您需要 $element-names[position() gt 1]
.
Example at https://xsltfiddle.liberty-development.net/3NzcBtK, for XSLT 2 you would need to spell out the identity transformation and I think instead of using head($element-names)
you would need to use element-names[1]
and instead of the tail
call on that variable you would need $element-names[position() gt 1]
.
这篇关于在 XML 中转义反斜杠并使用 XSLT 拆分为单独的 xml 节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!