This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
RE: problem with transforming-copying same level elements --2nd Posting--
- From: "Michael Kay" <michael dot h dot kay at ntlworld dot com>
- To: <xsl-list at lists dot mulberrytech dot com>
- Date: Thu, 28 Mar 2002 09:42:19 -0000
- Subject: RE: [xsl] problem with transforming-copying same level elements --2nd Posting--
- Reply-to: xsl-list at lists dot mulberrytech dot com
> For each <Body-Text> tag with string value of "To be eligible for CE
> credit", I need to create a <module> element and for each
> <question> tag
> create a child element named <assessment> and copy the xml/question,
> xml/answer and distractorList/distractor and their contents
> as childs of <assessment> tag.
>
Minor point, you shouldn't be using "<XML>" as an element name. It's
reserved.
In your example each Body-Text contains exactly one question and one answer?
If that's always true, then it's easy. I'm guessing that the real structure
is:
<body-text>
<question/>
<xxx/>
<answer/>
<xxx/>
<question/>
<xxx/>
<answer/>
<xxx/>
<question/>
<xxx/>
<answer/>
<xxx/>
</body-text>
This is a particularly knotty kind of grouping transformation. It's easy in
XSLT 2.0 (you can try this with Saxon 7.0):
<xsl:for-each-group group-starting-at="question">
<assessment>
<question><xsl:value-of select="current-group()/question"/></question>
<answer><xsl:value-of select="current-group()/question"/></answer>
</assessment>
It's harder with XSLT 1.0, but by no means impossible. I would do it along
the following lines:
<xsl:template match="Body-Text[.='.....']">
<module>
<xsl:apply-templates select="question[1]"/>
</module>
</xsl:template>
<xsl:template match="question">
<assessment>
<question><xsl:value-of select="."/></question>
<answer><xsl:value-of select="following-sibling::answer[1]"/></answer>
<assessment
<xsl:apply-templates select="following-sibling::question[1]"/>
</xsl:template>
I'm afraid I've abstracted from the detail of your actual input and output
here, you'll have to sort out the detail yourself. The <distraction>
elements might make the detail a fair bit more complicated than this; the
trick is to select those <distraction> elements whose
preceding-sibling::question[1] is the current question, which you can test
using generate-id().
Michael Kay
Software AG
home: Michael.H.Kay@ntlworld.com
work: Michael.Kay@softwareag.com
>
> TARGETED XML
> --------------------------
> <course>
> <module>
> <assessment>
> <question>
> <stem>
> <para>some text here</para>
> </stem>
> <answer> This is answer</answer>
> <distractor> This is distractor 1</distractor>
> <distractor> This is distractor 2</distractor>
> </question>
> </assessment>
> .....
> </module>
> <module>
> <assessment>
> <question>
> <stem>
> <para>some more text here</para>
> </stem>
> <distractor> This is another distractor 1</distractor>
> <answer>This is another answer</answer>
> <distractor> This is another distractor 2</distractor>
> <distractor> This is another distractor 3</distractor>
> </question>
> </assessment>
> .....
> </module>
> </course>
>
>
>
>
> INPUT XML
> -------------
> <XML>
> <Body-Text>To be eligible for CE credit</Body-Text>
> <question>some text here</question>
> <distractorList>
> <distractor>This is distractor 1</distractor>
> </distractorList>
> <answer>This is answer</answer>
> <distractorList>
> <distractor>This is distractor 2</distractor>
> <distractor>This is distractor 3</distractor>
> </distractorList>
> ......
> <Body-Text>To be eligible for CE credit</Body-Text>
> <question>some more text here</question>
> <distractorList>
> <distractor> This is another Distractor 1</distractor>
> </distractorList>
> <answer>This is another answer</answer>
> <distractorList>
> <distractor>This is another Distractor 2</distractor>
> <distractor>This is another Distractor 3</distractor>
> </distractorList>
> </XML>
>
>
> XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
>
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list