XSL转换的XML文本格式

时间:2011-05-11 16:41:02

标签: xml xslt

我希望我的头衔能够为这个问题伸张正义。请考虑以下XML块和XSL示例块。

<root>
<level_one>
My first line of text on level_one
<level_two>
My only line of text on level_two
</level_two>
My second line of text on level_one
</level_one>
</root>

<xsl:template match="level_one">
<xsl:value-of select="text()"/>
<br/>
<xsl:apply-templates select="level_two"/>
</xsl:template>

<xsl:template match="level_two">
<xsl:value-of select="text()"/>
<br/>
</xsl:template>

目前,执行上述操作时的输出(此处修改用于读取)是

My first line of text on level_one
<br/>
My only line of text on level_two
<br/>

我错过了level_one上的第二行文字。所以我想知道两件事。

  1. XML有效吗?据我所知,回答是肯定的,但我错了吗?
  2. 如何修改XSL以获得第二行(或者在我的情况下甚至比我显示的更多行)?
  3. 由于

3 个答案:

答案 0 :(得分:1)

使用xsl:apply-templates的递归下降的标准XSLT处理模型。

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

<xsl:template match="text()">
<xsl:value-of select="."/>
<br/>
</xsl:template>

使用<xsl:value-of select="text()"/>是个坏消息。在XSLT 1.0中,它只显示第一个文本节点(如您所发现的)。在XSLT 2.0中,它显示所有子文本节点,空格分隔,但这可能不是您想要的,因为它将在第二个之前输出第一个和第三个句子。 (实际上你还没有确切地说出你想要的输出,所以我不得不猜测。)

答案 1 :(得分:1)

即使没有匹配text()的模板,您也可以通过替换输出当前节点(text())的两个level_one节点子节点:

<xsl:value-of select="text()"/>

<强>与

<xsl:copy-of select="text()"/>

在XSLT 1.0中,知道<xsl:value-of select="$someNodeSet"/>仅生成$someNodeSet节点集的第一个节点(按文档顺序)的字符串值非常重要。

另一方

<xsl:copy-of select="$someNodeSet"/>

复制$someNodeSet中包含的所有节点。

答案 2 :(得分:0)

  

XML有效吗?据我所知,   回答是肯定的,但我错了吗?

是的,您的XML有效。另外,与上面的评论相反,在XML中混合内容(文本和元素混合在一起)没有任何问题。这完全取决于上下文以及XML的使用方式。例如,在没有混合内容的情况下编写技术手册几乎是不可能的。 (一个很好的例子是与段落元素中的文本混合的引用元素。)

  

如何修改XSL   得到第二行(甚至更多   在我的情况下,线条比我所示的?)

我不确定您要完成的是什么,但是您没有看到第二行文字的原因是因为您只将第一行与第一行<xsl:value-of select="text()"/>匹配。< / p>

我不确定这是否适用于您的全套XML数据,但您可以使用一个匹配所有level_one的模板替换level_twotext()模板:< / p>

  <xsl:template match="text()">
    <xsl:value-of select="."/>
    <br/>
  </xsl:template>

这会产生以下输出:

  My first line of text on level_one
  <br/>
  My only line of text on level_two
  <br/>
  My second line of text on level_one
  <br/>

您还可以通过指定level_one和level_two父级来缩小匹配范围:

  <xsl:template match="level_one/text()|level_two/text()">
    <xsl:value-of select="."/>
    <br/>
  </xsl:template>

这会产生完全相同的输出,但会打开任何其他文本以便在其他模板中进行匹配。

希望这有帮助。