感谢上一篇文章,我现在可以转换了
<root>
<parent>
<Jack>value1</Jack>
<Jane>value2</Jane>
<spArchie>value3</spArchie>
<spKate>value4</spKate>
</parent>
</root>
至
<root>
<parent>
<Jack>value1</Jack>
<Jane>value2</Jane>
<childlist>
<value name="spArchie">value3</value>
<value name="spKate">value4</value>
</childlist>
</parent>
</root>
使用以下XSLT
<xsl:template match="childlist[normalize-space(spArchie) or normalize-space(spKate)]">
<xsl:copy>
<xsl:apply-templates select="@* | node()[not(self::spArchie | self::spKate)]"/>
<childlist>
<xsl:apply-templates select="spArchie | spKate" mode="wrap"/>
</childlist>
</xsl:copy>
</xsl:template>
<xsl:template match="childlist[not('' = (../spArchie|../spKate))]">
<xsl:copy>
<xsl:apply-templates select="spArchie[normalize-space()] | spKate[normalize-space()]" mode="wrap"/>
</xsl:copy>
</xsl:template>
<xsl:template match="spArchie[normalize-space()] | spKate[normalize-space()]" mode="wrap">
<value name="{local-name()}">
<xsl:apply-templates/>
</value>
</xsl:template>
然而,到目前为止,在xml文档中,我还有许多与父节点处于同一级别的其他节点,我希望将相同的功能应用于这些节点,但使用不同的元素名称。I.e我也想换
<teacher>
<Rachel>value1</Rachel>
<spChristine>value2</spChristine>
<spPeter>value3</spPeter>
<Daisy>value4</Daisy>
</teacher>
至
<teacher>
<Rachel>value1</Rachel>
<Daisy>value4</Daisy>
<studentlist>
<value name="Christine">value2</value>
<value name="Peter">value3</value>
</studentlist>
</teacher>
很明显,我可以使用不同的值复制已经创建的xslt,但这个想法让我毛骨悚然(如果有人看到它,我会脸红)。有没有一种方法可以在循环中执行xslt,为我想要搜索和移动的节点传递参数。到目前为止,我的想法是
- 收集与父级处于同一级别的所有节点
- 查找前缀为sp的父节点的所有子节点
- 将这些a参数传递给我已经拥有的xslt
我正在寻求在实施这个解决方案时的反馈和建议。性能是一个关键问题。
非常感谢
我认为您的原始样式表可能更简单,也更通用:
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:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/root/*">
<xsl:copy>
<xsl:apply-templates select="*[not (starts-with(local-name(), 'sp'))]"/>
<childlist>
<xsl:apply-templates select="*[starts-with(local-name(), 'sp')]" mode="sp"/>
</childlist>
</xsl:copy>
</xsl:template>
<xsl:template match="*" mode="sp">
<value name="{local-name()}">
<xsl:apply-templates/>
</value>
</xsl:template>
</xsl:stylesheet>
然而,您不能将其直接应用于新的示例输入,因为:
- 结构不相同(没有父
root
元素) - 名称CCD_ 2必须来自某个地方
编辑:
但是,在xml文档中与父级相同,我想将相同的功能应用于
我错过了这个部分。如果它们在同一文档中并且在同一级别上,例如
XML
<root>
<parent>
<Jack>value1</Jack>
<Jane>value2</Jane>
<spArchie>value3</spArchie>
<spKate>value4</spKate>
</parent>
<teacher>
<Rachel>value1</Rachel>
<spChristine>value2</spChristine>
<spPeter>value3</spPeter>
<Daisy>value4</Daisy>
</teacher>
</root>
则上述样式表将返回:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<parent>
<Jack>value1</Jack>
<Jane>value2</Jane>
<childlist>
<value name="spArchie">value3</value>
<value name="spKate">value4</value>
</childlist>
</parent>
<teacher>
<Rachel>value1</Rachel>
<Daisy>value4</Daisy>
<childlist>
<value name="spChristine">value2</value>
<value name="spPeter">value3</value>
</childlist>
</teacher>
</root>