请参考问题"转义 XML 中的反斜杠并使用 XSLT 拆分为单独的 xml 节点" [英] Please refer to question " Escape backslash in XML and split as separate xml node using XSLT"
问题描述
我需要将以下 XML 转换为所需的输出-
I need to convert the following XML to desired output-
<?xml version="1.0" encoding="UTF-8"?>
<properties>
<entry>
<key>first_node/P_NODE</key>
<value>
<genericData>
<identifier>first_node/P_NODE</identifier>
<properties>
<entry>
<key>second_node</key>
<value>2</value>
</entry>
<entry>
<key>third_node/fourth_node/fifth_node</key>
<value>345</value>
</entry>
<entry>
<key>sixth_node/seventh_node</key>
<value>67</value>
</entry>
<entry>
<key>eigth_node</key>
<value>8</value>
</entry>
<entry>
<key>ninth_node</key>
<value>
<genericData>
<identifier>ninth_node</identifier>
<properties>
<entry>
<key>tenth_node</key>
<value>10</value>
</entry>
<entry>
<key>eleventh_node/twelveth_node</key>
<value>1112</value>
</entry>
</properties>
</genericData>
<genericData>
<identifier>ninth_node</identifier>
<properties>
<entry>
<key>x_node</key>
<value>10</value>
</entry>
<entry>
<key>y_node</key>
<value>1112</value>
</entry>
</properties>
</genericData>
</value>
</entry>
</properties>
</genericData>
</value>
</entry>
<entry>
<key>tirteenth_node</key>
<value>
<genericData>
<identifier>tirteenth_node</identifier>
<properties>
<entry>
<key>fourteenth_node</key>
<value>14</value>
</entry>
<entry>
<key>fifteenth_node/sixteenth_node</key>
<value>1516</value>
</entry>
</properties>
</genericData>
</value>
</entry>
<entry>
<key>seventeeth_node/eighteenth_node</key>
<value>1718</value>
</entry>
<entry>
<key>nineteenth_node/twenth_node</key>
<value>1920</value>
</entry>
<entry>
<key>twentyfirst_node</key>
<value>21</value>
</entry>
</properties>
期望的输出:
<?xml version="1.0" encoding="UTF-8"?>
<properties>
<first_node>
<P_NODE>
<second_node>2</second_node>
<third_node>
<fourth_node>
<fifth_node>345</fifth_node>
</fourth_node>
</third_node>
<sixth_node>
<seventh_node>67</seventh_node>
</sixth_node>
<eigth_node>8</eigth_node>
<ninth_node>
<tenth_node>10</tenth_node>
<eleventh_node>
<twelveth_node>1112</twelveth_node>
</eleventh_node>
</ninth_node>
<ninth_node>
<x_node>10</x_node>
<y_node>1112</y_node>
</ninth_node>
</P_NODE>
</first_node>
<tirteenth_node>
<fourteenth_node>14</fourteenth_node>
<fifteenth_node>
<sixteenth_node>1516</sixteenth_node>
</fifteenth_node>
</tirteenth_node>
<seventeeth_node>
<eighteenth_node>1718</eighteenth_node>
</seventeeth_node>
<nineteenth_node>
<twenth_node>1920</twenth_node>
</nineteenth_node>
<twentyfirst_node>21</twentyfirst_node>
</properties>
请让我知道可用于实现上述目的的 XSLT.
Kindly let me know the XSLT which can be used to achieve the above.
我使用了通过问题在 XML 中转义反斜杠并使用 XSLT 拆分为单独的 xml 节点".但是,当我对上述 XML 使用相同的代码时,它会打印父元素内的子元素,但也会打印为独立元素.注意:问题已被修改以代表实际问题陈述.
I have used the code which is answered through the question "Escape backslash in XML and split as separate xml node using XSLT". However, when I use the same code for the above XML, it is printing the child elements inside parent but also printing as standalone elements. Note: The question has been amended to represent the actual problem statement.
谢谢.
推荐答案
你首先需要添加第二个模板匹配 entry
节点,它下面有 genericData
将需要为每个这样的节点重复代码
You firstly need to add a second template matching entry
nodes which has genericData
under it, as you will need to repeat the code for each such node
<xsl:template match="entry[value/genericData]">
<xsl:for-each select="value/genericData">
<xsl:call-template name="splitter">
<xsl:with-param name="path" select="identifier" />
</xsl:call-template>
</xsl:for-each>
</xsl:template>
您还需要调整检查后代entry
节点的代码,使其只获取第一级entry
节点,而不是所有后代
You also need to tweak the code that checks for descendant entry
nodes, so that it only gets the first level of entry
nodes, not all descendants
<xsl:when test="self::genericData">
<xsl:apply-templates select="properties/entry" />
</xsl:when>
试试这个 XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="entry">
<xsl:call-template name="splitter">
<xsl:with-param name="path" select="key" />
<xsl:with-param name="value" select="value" />
</xsl:call-template>
</xsl:template>
<xsl:template match="entry[value/genericData]">
<xsl:for-each select="value/genericData">
<xsl:call-template name="splitter">
<xsl:with-param name="path" select="identifier" />
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="splitter">
<xsl:param name="path" />
<xsl:param name="value" />
<xsl:choose>
<xsl:when test="contains($path, '/')">
<xsl:element name="{substring-before($path, '/')}">
<xsl:call-template name="splitter">
<xsl:with-param name="path" select="substring-after($path, '/')" />
<xsl:with-param name="value" select="$value" />
</xsl:call-template>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="{$path}">
<xsl:choose>
<xsl:when test="self::genericData">
<xsl:apply-templates select="properties/entry" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$value" />
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
这篇关于请参考问题"转义 XML 中的反斜杠并使用 XSLT 拆分为单独的 xml 节点"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!