用于 XSL 转换的 XML 文本格式
我希望我的标题能够公正地回答这个问题。请考虑以下 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 上的第二行文本。所以我想知道两件事。
- XML 有效吗?据我所知,答案是肯定的,但是我错了吗?
- 如何修改 XSL 以获得第二行(或者在我的情况下比我显示的行更多)?
谢谢
I hope my title does justice for the question. Please consider the following block of XML and sample block of 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>
As it stands, the output (modified here for reading) when executing the above is
My first line of text on level_one
<br/>
My only line of text on level_two
<br/>
I'm missing the second line of text on level_one. So I'm wondering two things.
- Is the XML valid? From what I know, the answwer is yes, but am I wrong?
- How can I modify the XSL in order to get the second line (or even more lines in my case than I've shown)?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用 xsl:apply-templates 使用递归下降的标准 XSLT 处理模型。
使用
是个坏消息。在 XSLT 1.0 中,它仅显示第一个文本节点(正如您所发现的)。在 XSLT 2.0 中,它显示所有子文本节点,以空格分隔,但这可能不是您想要的,因为它将在第二个句子之前输出第一个和第三个句子。 (实际上你还没有确切地说出你想要什么输出,所以我不得不猜测。)Use the standard XSLT processing model of recursive descent using xsl:apply-templates.
Using
<xsl:value-of select="text()"/>
is bad news. In XSLT 1.0 it only displays the first text node (as you have discovered). In XSLT 2.0 it displays all the child text nodes, space separated, but this probably isn't what you want because it will output the first and third sentences before the second. (Actually you haven't said exactly what output you want so I'm having to guess.)即使没有匹配
text()
的模板,您也可以通过 输出当前节点 (level_one
) 的两个text()
子节点>替换:为:
在 XSLT 1.0 中,了解只产生字符串值
$someNodeSet
节点集的第一个节点(按文档顺序)。
另一边:
复制
$someNodeSet
中包含的所有节点。Even without a template matching
text()
, you can output the twotext()
node children of the current node (level_one
) by replacing:with:
In XSLT 1.0 it is very important to know that
<xsl:value-of select="$someNodeSet"/>
produces the string value of only the first node (in document order) of the$someNodeSet
node-set.On the other side:
copies all nodes contained in
$someNodeSet
.是的,您的 XML 是有效的。另外,与上面的评论相反,在 XML 中混合内容(文本和元素混合在一起)并没有什么问题。这完全取决于上下文以及 XML 的使用方式。例如,如果没有混合内容,几乎不可能编写技术手册。 (一个很好的例子是参考元素与段落元素中的文本混合。)
我不确定您想要完成什么,但您没有看到第二行文本的原因是因为您仅将第一行与第一个
。我不确定这是否适用于您的全套 XML 数据,但您可以将
level_one
和level_two
模板替换为与所有文本匹配的一个模板()
:这会产生以下输出:
您还可以通过指定 level_one 和 level_two 父级来缩小匹配范围:
这会产生完全相同的输出,但会保留任何其他文本以在其他模板中进行匹配。
希望这有帮助。
Yes your XML is valid. Also, contrary to a comment above, there is nothing wrong with having mixed content (text and elements mixed together) in XML. It all depends on context and how the XML is used. For example, it would be almost impossible to author technical manuals without mixed content. (A good example is reference elements mixed with text in paragraph elements.)
I'm not sure exactly what you're trying to accomplish, but the reason you're not seeing the second line of text is because you're only matching the first line with the first
<xsl:value-of select="text()"/>
.I'm not sure if this would work on your full set of XML data, but you could replace both
level_one
andlevel_two
templates with one template that matches alltext()
:This produces the following output:
You could also narrow the match down by specifying the level_one and level_two parents:
This produces the exact same output, but leaves any other text open for matching in other templates.
Hope this helps.