我需要将父节点的副本移动到多个子节点中,而无需在此过程中复制所述子节点本身。这是一个示例 XML:
<FoodGroups>
<Nutritional>Yes</Nutritional>
<Artifical>No</Artificial>
<FoodGroup>
<Fruit>Grape</Fruit>
<Fruit>Apple</Fruit>
</FoodGroup>
<FoodGroup>
<Vegetable>Carrot</Vegetable>
<Vegetable>Potato</Vegetable>
<FoodGroup>
</FoodGroups>
转换完成后,我需要 XML 如下所示:
<xml>
<FoodGroup>
<Fruit>Grape</Fruit>
<Fruit>Apple</Fruit>
<FoodGroups>
<Nutritional>Yes</Nutritional>
<Articial>No</Artificial>
</FoodGroups>
</FoodGroup>
<FoodGroup>
<Vegetable>Carrot</Vegetable>
<Vegetable>Potato</Vegetable>
<FoodGroups>
<Nutritional>Yes</Nutritional>
<Articial>No</Artificial>
</FoodGroups>
<FoodGroup>
</xml>
我试过使用以下 XML:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl">
<xsl:output omit-xml-declaration="yes"
method="xml"
indent="yes"/>
<xsl:template match="/">
<xml>
<xsl:copy>
<xsl:apply-templates select="//FoodGroup"/>
</xsl:copy>
</xml>
</xsl:template>
<xsl:template match="//FoodGroup">
<FoodGroup>
<xsl:copy-of select="./*"/>
<xsl:copy-of select="//FoodGroups/*[not(child::FoodGroup)]"/>
</FoodGroup>
</xsl:template>
</xsl:stylesheet>
但是,我得到以下输出(子节点完全重新复制——我不想要这个):
<xml>
<FoodGroup>
<Fruit>Grape</Fruit>
<Fruit>Apple</Fruit>
<FoodGroups>
<Nutritional>Yes</Nutritional>
<Artifical>No</Artificial>
<FoodGroup>
<Fruit>Grape</Fruit>
<Fruit>Apple</Fruit>
</FoodGroup>
<FoodGroup>
<Vegetable>Carrot</Vegetable>
<Vegetable>Potato</Vegetable>
<FoodGroup>
</FoodGroups>
</FoodGroup>
<FoodGroup>
<Vegetable>Carrot</Vegetable>
<Vegetable>Potato</Vegetable>
<FoodGroups>
<Nutritional>Yes</Nutritional>
<Artifical>No</Artificial>
<FoodGroup>
<Fruit>Grape</Fruit>
<Fruit>Apple</Fruit>
</FoodGroup>
<FoodGroup>
<Vegetable>Carrot</Vegetable>
<Vegetable>Potato</Vegetable>
<FoodGroup>
</FoodGroups>
<FoodGroup>
</xml>
这种亲子复制能做吗?是否可以?部分困难在于,有时这些孩子的深度不止一层。
以下似乎可以完成这项工作:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xml>
<xsl:apply-templates/>
</xml>
</xsl:template>
<xsl:template match="FoodGroups">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="FoodGroups/*[not(self::FoodGroup)]"/>
<xsl:template match="FoodGroup">
<xsl:copy>
<xsl:apply-templates/>
<FoodGroups>
<xsl:copy-of select="ancestor::FoodGroups/*[not(self::FoodGroup)]"/>
</FoodGroups>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
为什么不简单(而且更有效):
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/FoodGroups">
<xml>
<xsl:variable name="common" select="*[not(self::FoodGroup)]" />
<xsl:for-each select="FoodGroup">
<xsl:copy>
<xsl:copy-of select="*"/>
<FoodGroups>
<xsl:copy-of select="$common"/>
</FoodGroups>
</xsl:copy>
</xsl:for-each>
</xml>
</xsl:template>
</xsl:stylesheet>