2010-09-02 53 views
1

我有一个XMLXSLT的,每个问题

<Root> 
    <Parent> 
    <Child1>A</Child1> 
    <Child2>B</Child2> 
    <Child1>X</Child1> 
    <Child2>Y</Child2> 
    </Parent> 
</Root> 

CHILD2总是将与child1。我需要知道如何循环使用xsl:foreach并创建XML输出示例。

<TransformedXML> 
    <Child attribute1="A" attribute2="B"/> 
    <Child attribute1="X" attribute2="Y"/> 
</TransformedXML> 

我的问题是我如何在XSLT中循环考虑Child2节点总是遵循Child1?

+0

好问题(+1)。看到我的答案是一个简短而有效的解决方案。 – 2010-09-02 00:52:23

回答

1

这种转变

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:key name="kFollowingChild1" match="*[not(self::Child1)]" 
    use="generate-id(preceding-sibling::Child1[1])"/> 

<xsl:template match="Parent"> 
    <TransformedXML> 
    <xsl:apply-templates/> 
    </TransformedXML> 
</xsl:template> 

<xsl:template match="Child1"> 
    <Child> 
    <xsl:for-each select=".|key('kFollowingChild1', generate-id())"> 
    <xsl:attribute name="attribute{position()}"> 
     <xsl:value-of select="."/> 
    </xsl:attribute> 
    </xsl:for-each> 
    </Child> 
</xsl:template> 

<xsl:template match="text()"/> 
</xsl:stylesheet> 

时所提供的应用(校正多次成为国内形成的!)XML文档

<Root> 
    <Parent> 
     <Child1>A</Child1> 
     <Child2>B</Child2> 
     <Child1>X</Child1> 
     <Child2>Y</Child2> 
    </Parent> 
</Root> 

产生想要的,正确的结果

<TransformedXML> 
    <Child attribute1="A" attribute2="B"/> 
    <Child attribute1="X" attribute2="Y"/> 
</TransformedXML> 
+0

谢谢。此外,如果myChild是什么 X Ÿ 我怎样才能环路直通的child1得到小与上述XSLT。我很困惑,为什么我得到内在的文本。 – Greens 2010-09-02 02:33:39

+0

@绿色:我不明白 - 请描述得更好。你想得到什么结果(XML,请)? – 2010-09-02 02:45:20

+0

INPUT Xý ---------------------------- -------- OUTPUT Greens 2010-09-02 02:51:08

0

为什么你不想使用xsl:for-each是否有特定的原因?我建议只使用匹配模板:

<xsl:template match="Child1"> 
    <Child attribute1="{.}" attribute2="{following-sibling::*[1]}"/> 
</xsl:template> 

<xsl:template match="Child2"/> 

这会就好了工作,只要前提是Child1始终将Child2先上后下的兄弟姐妹。