下面是我的xml文件 .
<xml>
<top>
<main>
<firstname>John</firstname>
<lastname>John</lastname>
<table></table>
<chapter>
<firstname>Alex</firstname>
<lastname>Robert</lastname>
<p>Sample text chap</p>
<figure name="f1.svg"></figure>
<chapter>
<firstname>Rebec</firstname>
<lastname></lastname>
<p>Sample text</p>
<figure name="f2.svg"></figure>
</chapter>
</chapter>
</main>
</top>
</xml>
Desired output:
<bold>John
table
<bold>Robert
Sample text chap
f1.svg
<bold> Rebec
Sample text
f2.svg
Explaination: 我写了一个xslt来做这件事 . 我需要动态获取xml节点 . 我不能写:xsl:apply-templates select = 'main/lastname' . 因为我的xml格式可以随时更改 . 我尝试过使用'$root/*'首先获取所有xml节点的逻辑 . 然后,如果遇到'table'元素,我使用xsl:apply-templates select = 'current()[name() = ' TABLE ']'并执行表创建操作 . 这很好用 . 我得到了所需的输出,但我的图形元素只在输出的每个位置显示f1.svg . f2.svg未显示 . 我如何只匹配'lastname'并使其变为粗体?我想使代码尽可能通用/模块化,以便它遍历xml树的所有元素,并在特定节点上进行一些格式化 . 下面是递归的xslt . 有了这个,我的数据就会重复出现 . 我正在编写递归模板,因为xslt不是顺序的 .
XSLT:
<xsl:call-template name="FetchNodes">
<xsl:with-param name="endIndex" select="$NumberOfNodes" />
<xsl:with-param name="startIndex" select="1" />
<xsl:with-param name="context" select="$root/*" />
</xsl:call-template>
<xsl:template name="FetchNodes">
<xsl:param name="endIndex" />
<xsl:param name="startIndex" />
<xsl:param name="context" />
<xsl:if test="$startIndex <= $endIndex">
<xsl:if test="$context[$startIndex][name() = 'table']"">
<xsl:apply-templates select="$context[$startIndex][name() = 'table']"" mode="table" />
</xsl:if>
<xsl:call-template name="FetchNodes">
<xsl:with-param name="endIndex" select="$endIndex" />
<xsl:with-param name="startIndex" select="$startIndex + 1"/>
<xsl:with-param name="context" select="$context" />
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="node()" mode="table">
<xsl:value-of select="node()" />
</xsl:template>
使用上面的xslt,应用模板的xpath中有些内容不正确 . 输出不合适 .
我想要XSL FO输出 .
任何人都可以提出建议吗?
1 回答
显示“f1.svg”而不是“f2.svg”的问题是因为这一行
此时您已经定位在 figure 上,因此您只需要在此处使用相对xpath表达式 . 您当前使用的是绝对路径,因此无论您的上下文如何,它都将始终返回第一个 @name 属性 . 应该看看这个
或者更好,就像这样
话虽如此,代码在一个模板中,试图匹配一个元素 FIGURE 元素,这个元素在你向我们展示的XML中不存在 . 例如,您实际上可以简化模板匹配
至于使事情变粗,您只需将 font-weight 属性添加到要制作粗体的任何块 . 像这样的东西:
EDIT: 尽管如此,你可能没有采取正确的方法解决问题 . 使用模板匹配可能会更好,利用XSLT的内置模板来浏览文档 . 基本上,只需为要匹配的每个元素编写一个模板,然后生成输出,然后继续匹配其子元素 .
例如,要将 chapter 变为 fo:block ,请执行此操作
要以粗体输出 firstname ,请执行此操作
要将 figure 转换为图像,请执行此操作(请注意,此处使用属性值模板,花括号表示要计算的表达式,而不是字面输出)
试试这个XSLT作为起点,并以此为基础