我希望我的头衔能够为这个问题伸张正义。请考虑以下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上的第二行文字。所以我想知道两件事。
由于
答案 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_two
和text()
模板:< / 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>
这会产生完全相同的输出,但会打开任何其他文本以便在其他模板中进行匹配。
希望这有帮助。