2010-09-02 3 views
1

У меня есть XMLXSLT для каждого вопроса-

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

Child2 всегда будет с ребенка1. Мне нужно знать, как я могу выполнить цикл с помощью xsl:foreach и создать пример вывода XML.

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

Мой вопрос в том, как я могу зацикливаться на XSLT, учитывая, что узел Child2 будет всегда следовать за Child1?

+0

Хороший вопрос (+1). См. Мой ответ для краткого и эффективного решения. –

ответ

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 является B X Y Как петля через ребенка1 получить небольшие с вышеизложенным XSLT. Я смущен, почему я получаю внутренний текст. – Greens

+0

@ Зеленые: Я не понимаю - пожалуйста, опишите лучше. Что вы хотите получить в результате (XML, пожалуйста)? –

+0

ВХОД В Х У ---------------------------- -------- OUTPUT <Детский атрибут1 = "A" anyName = "1" attribute2 = "B" /> <Детский атрибут1 = "X" attribute2 = "Y" /> Greens

0

Есть ли конкретная причина, по которой вы не используете xsl:for-each? Я хотел бы предложить, чтобы просто использовать соответствующие шаблоны:

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

<xsl:template match="Child2"/> 

Это будет прекрасно работать до тех пор, как необходимое условие, что Child1 всегда будет первый следующий родственный Child2.

Смежные вопросы