下面是一个示例XML。
<Root>
<Story>
<body>
<quiz>1</quiz>How to select that rightanswer from another Story ?
</body>
<answer>answer1-1</answer>
<answer>answer1-2</answer>
<answer>answer1-3</answer>
<body>
<quiz>2</quiz>And how to push these <qitem/>s into <qitems/> ?
</body>
<answer>answer2-1</answer>
<answer>answer2-2</answer>
<answer>answer2-3</answer>
<answer>answer2-4</answer>
</Story>
<Story>
<h3>RIGHT_ANSWERS</h3>
<rightanswer>
RightAnswer1 IDK
</rightanswer>
<rightanswer>
RightAnswer2 IDK
</rightanswer>
</Story>
</Root>
预期输出:
<Root>
<Story>
<quiz>
<qitems>
<qitem>
<question>
<qtitle>1</qtitle>
<qtext>How to select that rightanswer from another Story ?</qtext>
</question>
<answers>
<answer>answer1-1</answer>
<answer>answer1-2</answer>
<answer>answer1-3</answer>
</answers>
<rightanswer>RightAnswer1 IDK</rightanswer>
</qitem>
<qitem>
<question>
<qtitle>2</qtitle>
<qtext>And how to push these <qitem/>s into <qitems/> ?</qtext>
</question>
<answers>
<answer>answer2-1</answer>
<answer>answer2-2</answer>
<answer>answer2-3</answer>
<answer>answer2-4</answer>
</answers>
<rightanswer>RightAnswer2 IDK</rightanswer>
</qitem>
</qitems>
</quiz>
</Story>
</Root>
我所要做的就是将每个body[quiz]
及其以下名为answer
的同级放入<qitem>
元素中,并将这些<qitem>s
推入父<qitems>
并选择<rightanswer>
。到目前为止,我有这个xsl:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="body[quiz]" >
<qitem>
<question>
<qtitle>
<xsl:value-of select="quiz" />
</qtitle>
<qtext>
<xsl:apply-templates select="node()" />
</qtext>
</question>
<answers>
<xsl:apply-templates select="following-sibling::*[1][self::answer]" mode="following" />
</answers>
<rightanswer></rightanswer>
</qitem>
</xsl:template>
<xsl:template match="answer" mode="following">
<answer>
<xsl:apply-templates select="node()" />
</answer>
<xsl:apply-templates select="following-sibling::*[1][self::answer]" mode="following" />
</xsl:template>
<xsl:template match="body/quiz" />
<xsl:template match="answer" />
<xsl:template match="h3"/>
</xsl:stylesheet>
看看这个:http://xsltransform.net/nc4NzQr
如果可以假设Root
元素总是恰好包含2个Story
元素,其中一个元素的Q&作为一个有正确答案的人,那么你可以简单地做:
XSLT 1.0
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Story[1]">
<qitems>
<xsl:apply-templates select="body"/>
</qitems>
</xsl:template>
<xsl:template match="body">
<xsl:variable name="i" select="position()" />
<qitem>
<question>
<qtitle>
<xsl:value-of select="quiz" />
</qtitle>
<qtext>
<xsl:apply-templates/>
</qtext>
</question>
<answers>
<xsl:apply-templates select="following-sibling::answer[1]" mode="following"/>
</answers>
<xsl:apply-templates select="following::Story/rightanswer[$i]"/>
</qitem>
</xsl:template>
<!-- sibling recursion -->
<xsl:template match="answer" mode="following">
<answer>
<xsl:apply-templates/>
</answer>
<xsl:apply-templates select="following-sibling::*[1][self::answer]" mode="following" />
</xsl:template>
<xsl:template match="Story[2]" />
<xsl:template match="quiz" />
</xsl:stylesheet>
在将这些
<qitem>
推入父<qitems>
时陷入困境
我不明白你为什么需要<qitems>
包装器,它代表什么;在我看来,您请求的输出中已经有太多的包装器元素了。在上面的示例中,我使<qitems>
表示父Story
,并删除了Story
包装本身。