我正在尝试将XML文件转换为带有一些选定节点的规范化XML。 我将节点名称的路径保存在一个变量中,如下所示:
<xsl:variable name="nodePath">
<path>class/id</path>
<path>class/title</path>
<path>class/description_url</path>
<path>class/duration</path>
</xsl:variable>
XML示例数据:
<?xml version="1.0" encoding="utf-8" ?>
<table>
<other_node>Ignore</other_node>
<class>
<id>Test Data</id>
<title>Testing</title>
<description_url>Test Data</description_url>
<duration>2</duration>
</class>
<class>
<id>Test Data</id>
<title>Testing</title>
<description_url>Test Data</description_url>
<duration>2</duration>
<other_node>Ignore</other_node>
</class>
<class>
<id>Test Data</id>
<title>Testing</title>
<description_url>Test Data</description_url>
<duration>2</duration>
</class>
</table>
输出:
<rows>
<row>
<id>Test Data</id>
<title>Testing</title>
<description_url>Test Data</description_url>
<duration>2</duration>
</row>
<row>
<id>Test Data</id>
<title>Testing</title>
<description_url>Test Data</description_url>
<duration>2</duration>
</row>
<row>
<id>Test Data</id>
<title>Testing</title>
<description_url>Test Data</description_url>
<duration>2</duration>
</row>
</rows>
请帮忙。提前谢谢。
答案 0 :(得分:1)
我不认为你提出这个问题时会解决问题,但你可以做类似的事情。有问题的是你没有真正列出你想要保留的所有元素的路径,例如你仍然需要table
和class
,即使它们没有在变量中列出,也是如此寻找文本(文本也是一个节点)。
然后您的变量包含相对路径,并且不清楚它们应用于输入树中的哪个级别。解决此问题的方法是使用level
属性指示表达式的级别。
从变量中读取路径表达式在XSLT 1.0中引入了两个难点:
xsl:variable
内的元素,即使用它作为结果树片段,在标准XSLT 1.0中是不可能的。使用exsl:node-set()
。dyn:evaluate()
。<强>样式表强>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:dyn="http://exslt.org/dynamic"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="dyn exsl">
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="nodePath">
<path level="1">class</path>
<path level="2">id</path>
<path level="2">title</path>
<path level="2">description_url</path>
<path level="2">duration</path>
</xsl:variable>
<xsl:template match="/table">
<xsl:variable name="context" select="."/>
<xsl:copy>
<xsl:for-each select="exsl:node-set($nodePath)/*[@level = '1']">
<xsl:apply-templates select="dyn:evaluate(concat('$context/',.))"/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="/table/*">
<xsl:variable name="context" select="."/>
<xsl:copy>
<xsl:for-each select="exsl:node-set($nodePath)/*[@level = '2']">
<xsl:apply-templates select="dyn:evaluate(concat('$context/',.))"/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="/table/*/*">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
XML输出
<?xml version="1.0" encoding="UTF-8"?>
<table>
<class>
<id>Test Data</id>
<title>Testing</title>
<description_url>Test Data</description_url>
<duration>2</duration>
</class>
<class>
<id>Test Data</id>
<title>Testing</title>
<description_url>Test Data</description_url>
<duration>2</duration>
</class>
<class>
<id>Test Data</id>
<title>Testing</title>
<description_url>Test Data</description_url>
<duration>2</duration>
</class>
</table>