我知道这里有一些内容,但我是XSLT的新手,我正在尝试在输入XML中位于不同位置但在同一节点级别的节点上执行嵌套for-each循环。
所以...例如:
<Level1>
<Level2>
<Level3a>
<Item1>Clothes Washed</Item1>
<Item2>08/02/2011 06:54</Item2>
<DoneBy>Ingrid</DoneBy>
</Level3a>
<Level3a>
<Item1>Car Washed</Item1>
<Item2>08/02/2011 08:25</Item2>
<DoneBy>Jeanette</DoneBy>
</Level3a>
<Level3a>
<Item1>Dog Walked</Item1>
<Item2>08/02/2011 10:30</Item2>
<DoneBy>Ingrid</DoneBy>
</Level3a>
<Level3b>
<DoneWho>Ingrid</DoneWho>
<JobTitle>Main Asst</JobTitle>
</Level3b>
<Level3b>
<DoneWho>Jeanette</DoneWho>
<JonTitle>2nd Asst</JobTitle>
</Level3b>
</Level2>
</Level1>
我需要输出
<Jobs>
<CompletedJob>
<JobTitle>Main Asst</JobTitle>
<Job>Clothes Washed</Job>
<CompOn>08/02/2011</CompOn>
<CompAt>06:54<CompAt>
</CompletedJob>
<CompletedJob>
<JobTitle>Main Asst</JobTitle>
<Job>Dog Walked</Job>
<CompOn>08/02/2011</CompOn>
<CompAt>10:30</CompAt>
</CompletedJob>
<CompletedJob>
<JobTitle>2nd Asst</JobTitle>
<Job>Car Washed</Job>
<CompOn>08/02/2011</CompOn>
<CompAt>08:25</CompAt>
</CompletedJob>
</Jobs>
编辑:请看上面输出中的变化......我想这正是我想要做的。
用...取代输出再次感谢。
我已尝试过每个循环的neste,但我不能在主for-each循环内引用不同的节点。
非常感谢任何帮助。
答案 0 :(得分:1)
不需要嵌套循环 - XSLT本质上是递归的。
以下样式表完成工作:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="/">
<Jobs>
<xsl:for-each select="*/*/Level3a">
<xsl:sort select="DoneBy"/>
<CompletedJob>
<JobTitle>
<xsl:value-of select="../Level3b[DoneWho=current()/DoneBy]/JobTitle"/>
</JobTitle>
<Job>
<xsl:value-of select="Item1"/>
</Job>
<CompOn>
<xsl:value-of select="substring-before(Item2,' ')"/>
</CompOn>
<CompAt>
<xsl:value-of select="substring-after(Item2,' ')"/>
</CompAt>
</CompletedJob>
</xsl:for-each>
</Jobs>
</xsl:template>
</xsl:stylesheet>
现在使用Level 3b元素将DoneBy解析为JobTitle。
答案 1 :(得分:1)
您不必使用嵌套循环(或循环)。
使用输入XML的固定版本:
<Level1>
<Level2>
<Level3a>
<Item1>Clothes Washed</Item1>
<Item2>08/02/2011 06:54</Item2>
<DoneBy>Ingrid</DoneBy>
</Level3a>
<Level3a>
<Item1>Car Washed</Item1>
<Item2>08/02/2011 08:25</Item2>
<DoneBy>Jeanette</DoneBy>
</Level3a>
<Level3a>
<Item1>Dog Walked</Item1>
<Item2>08/02/2011 10:30</Item2>
<DoneBy>Ingrid</DoneBy>
</Level3a>
<Level3b>
<DoneWho>Ingrid</DoneWho>
<JobTitle>Main Asst</JobTitle>
</Level3b>
<Level3b>
<DoneWho>Jeanette</DoneWho>
<JobTitle>2nd Asst</JobTitle>
</Level3b>
</Level2>
</Level1>
和这个样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/Level1">
<Jobs>
<xsl:apply-templates select="*/Level3a">
<xsl:sort select="DoneBy"/>
</xsl:apply-templates>
</Jobs>
</xsl:template>
<xsl:template match="Level3a">
<CompletedJob>
<Who><xsl:apply-templates select="DoneBy"/></Who>
<Job><xsl:apply-templates select="Item1"/></Job>
<!-- XSLT 2.0 option
<CompOn><xsl:value-of select="tokenize(Item2,' ')[1]"></xsl:value-of></CompOn>
<CompAt><xsl:value-of select="tokenize(Item2,' ')[2]"></xsl:value-of></CompAt>
-->
<CompOn><xsl:value-of select="substring-before(Item2, ' ')"></xsl:value-of></CompOn>
<CompAt><xsl:value-of select="substring-after(Item2, ' ')"></xsl:value-of></CompAt>
</CompletedJob>
</xsl:template>
<xsl:template match="DoneBy|Item1|Item2">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
产生想要的输出:
<Jobs>
<CompletedJob>
<Who>Ingrid</Who>
<Job>Clothes Washed</Job>
<CompOn>08/02/2011</CompOn>
<CompAt>06:54</CompAt>
</CompletedJob>
<CompletedJob>
<Who>Ingrid</Who>
<Job>Dog Walked</Job>
<CompOn>08/02/2011</CompOn>
<CompAt>10:30</CompAt>
</CompletedJob>
<CompletedJob>
<Who>Jeanette</Who>
<Job>Car Washed</Job>
<CompOn>08/02/2011</CompOn>
<CompAt>08:25</CompAt>
</CompletedJob>
</Jobs>
注意:到目前为止,我的答案是唯一一个对输出进行排序并产生您想要的精确结果(减去格式错误)的答案。
答案 2 :(得分:0)
Darn,打败我吧。哦,不妨也提出我的解决方案:
<Level1>
<Level2>
<Level3>
<Item1>Clothes Washed</Item1>
<Item2>08/02/2011 06:54</Item2>
<DoneBy>Ingrid</DoneBy>
</Level3>
<Level3>
<Item1>Car Washed</Item1>
<Item2>08/02/2011 08:25</Item2>
<DoneBy>Jeanette</DoneBy>
</Level3>
<Level3>
<Item1>Dog Walked</Item1>
<Item2>08/02/2011 10:30</Item2>
<DoneBy>Ingrid</DoneBy>
</Level3>
</Level2>
</Level1>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<Jobs>
<xsl:for-each select="/Level1/Level2/Level3">
<CompletedJob>
<Who><xsl:value-of select="./DoneBy"/></Who>
<Job><xsl:value-of select="./Item1"/></Job>
<CompOn><xsl:value-of select="substring(./Item2, 1, 10)"/></CompOn>
<CompAt><xsl:value-of select="substring(./Item2, 12, 5)"/></CompAt>
</CompletedJob>
</xsl:for-each>
</Jobs>
</xsl:template>
</xsl:stylesheet>
答案 3 :(得分:0)
你的xml输入非常可怕。
<xsl:template match="/">
<xsl:apply-templates select="//Item1"/>
</xsl:template>
<xsl:template match="Item1">
<CompletedJob>
<Who><xsl:value-of select="../DoneBy"/></Who>
<Job><xsl:value-of select="."/></Job>
<xsl:apply-templates select="../Item2"/>
</CompletedJob>
</xsl:template>
<xsl:template match="Item2">
<CompOn><xsl:value-of select="substring-before(text(), ' ')"/></CompOn>
<CompAt><xsl:value-of select="substring-after(text(), ' ')"/></CompAt>
</xsl:template>
这会生成输出