我是XSLT的新手,我正在尝试利用它来基于指定的属性重新创建(复制)现有的xml文档。
例如,在下面的XML中,我想从具有group =“ Book1”属性的mainGroup中获得具有tag =“ 6”属性的课程
<Groups>
<mainGroup id="1" group="Book1">
<subGroup name="Chapter 1">
<lesson name="Lesson1" tags="1" />
<lesson name="Lesson2" tags="2" />
</subGroup>
<subGroup name="Chapter 2">
<lesson name="Lesson1" tags="3" />
<lesson name="Lesson2" tags="4" />
</subGroup>
<subGroup name="Chapter 3">
<subGroup name="Chapter 3 Examples">
<lesson name="Lesson2" tags="5" />
</subGroup>
<lesson name="Lesson1" tags="6" />
</subGroup>
</mainGroup>
<mainGroup id="1" group="Book2">
<subGroup name="Chapter 1">
<lesson name="Lesson1" tags="1" />
<lesson name="Lesson2" tags="2" />
</subGroup>
<subGroup name="Chapter 2">
<lesson name="Lesson1" tags="3" />
<lesson name="Lesson2" tags="4" />
</subGroup>
<subGroup name="Chapter 3">
<subGroup name="Chapter 3 Examples">
<lesson name="Lesson2" tags="6" />
</subGroup>
<lesson name="Lesson1" tags="5" />
</subGroup>
</mainGroup>
</Groups>
在应用XSL之后具有以下预期(预期)结果
<Groups>
<mainGroup id="1" group="Book1">
<subGroup name="Chapter 3">
<lesson name="Lesson1" tags="6" />
</subGroup>
</mainGroup>
</Groups>
就XSL而言,到目前为止我想到的最接近的是:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
// Remove all maingroups that are not book1
<xsl:template match="mainGroup[not(@group='Book1')]" />
// Remove all lessons that do not have tags of 5
<xsl:template match="lesson[not(@tags='5')]" />
</xsl:stylesheet>
这给了我XML的结果:
<Groups>
<mainGroup id="1" group="Book1">
<subGroup name="Chapter 1" />
<subGroup name="Chapter 2" />
<subGroup name="Chapter 3">
<subGroup name="Chapter 3 Examples">
<lesson name="Lesson2" tags="5" />
</subGroup>
</subGroup>
</mainGroup>
</Groups>
我现在不知道如何删除空的子组-
我尝试过的一些事情(再次请不要笑-此XSL的新功能:))
希望这消除了那些没有课程节点的东西-但似乎什么也没做
<xsl:template match="subGroup[count(lesson) = 0]" />
<xsl:template match="subGroup[not(node())]" />
甚至像这样的东西
<xsl:template match="subGroups" mode="copy">
<xsl:choose>
<xsl:when test="count(./*)">
<xsl:copy>
<xsl:apply-templates select="@*|node()" mode="copy"/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
但是经过数小时没有成功之后,我却不知所措-我确定这里的某人可能正在读这本书-嗯,您只需要添加或执行此操作-任何帮助将不胜感激。
谢谢
关键是模板规则与输入XML相匹配,因此您必须取消subGroup
不包含所需课程的那些元素:
<xsl:template match="subGroup[not(.//lesson/@tags = '5')]"/>
对于子组最终将为空的规则更加复杂的情况,进行两阶段转换可能会更容易,首先进行当前操作,然后进行第二阶段处理,以完成第一阶段的结果到第二阶段的结果。去除剩余的空标签。在XSLT 2.0中,这很简单
<xsl:variable name="pass1">
<xsl:apply-templates />
</xsl:variable>
<xsl:apply-templates select="$pass1" mode="pass2"/>
但在1.0中,它需要node-set
扩展功能。如果您想走这条路线,可以在其他问题中找到很多这种技术的例子。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句