我正在制作一个XSLT模板,以便将XML转换为LaTeX(然后是HTML)。我认为XSLT不是为此而制作的,但它确实有效。我唯一的问题是文本格式:如果在某些文本行中,我想使用粗体或斜体字词,则语法为“< i>< / i >”中例如,在HTML中,但在LaTeX中是“\ textit {}”。
一种解决方案是将“i”声明为模板,但我不知道是否可以“自动”为每个被加载的文本块应用它(我不想在所有模板中明确地调用它)< / p>
抱歉,我是这项技术的新手,可能存在非常简单的解决方案,但Google这次没有帮助我。
任何建议都将受到赞赏。
编辑:例如:
Xsl:
<xsl:template match="one">
<xsl:apply-templates select="two"/>
</xsl:template>
XML:
<one>
<two>Some text with <i>italic</i> words</two>
</one>
期望的输出:
"Some text with \textit{italic} words"
我不想这样做:
<xsl:apply-templates select="i"/>
在我的所有模板中
所以我正在寻找一种方法来“全局”应用“i”模板。
答案 0 :(得分:3)
就这么简单:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="i">
<xsl:text>\textit{</xsl:text>
<xsl:apply-templates/>
<xsl:text>}</xsl:text>
</xsl:template>
</xsl:stylesheet>
在提供的XML文档上应用此转换时:
<one>
<two>Some text with <i>italic</i> words</two>
</one>
产生了想要的正确结果:
Some text with \textit{italic} words
<强>解释强>:
XSLT处理模型使用多个built-in templates,如果XSLT程序员不提供与特定节点匹配的模板,则使用该"push-style"提供任何XML文档的默认处理。
特别是,任何元素节点的内置模板,只需发出<xsl:apply-templates/>
,以便模板应用于其所有子节点。
任何文本节点的内置模板都是将此文本节点复制到输出。
这意味着我们不需要为节点提供任何模板,如果它必须与相应的内置模板完全相同。
只留下i
元素 - 所以我们提供了匹配i
的模板 - 它只是用“\ textit {”和“}”来处理其子元素的结果。
请注意:
完全可以表达复杂的转换,而无需指定单个<xsl:apply-templates>
,<xsl:call-template>
,<xsl:for-each>
,<xsl:choose>
,<xsl:when>
,{{1 }和<xsl:otherwise>
。
这称为"pull-style",而不是{{3}} ,其中广泛使用了其中一条或任何一条指令。
“推”式表达了问题的最具声明性的解决方案,而“拉式”转换表达了更“必要”的解决方案。
这是XSLT的精神,并建议尽可能多地生成“推送”代码。
答案 1 :(得分:0)
编辑:我现在最后添加了一个完整的XSL,基于OP的XML和XSL
这只是一个假设,因为---正如Dimitre在评论中所指出的那样 - 我们无法准确地看到你的XSL,输入或所需的输出。但是,你可能想要这样的东西。
<xsl:template match="//i">
<xsl:text>\textit{</xsl:text>
<xsl:apply-templates select="@*|node()"/>
<xsl:text>}</xsl:text>
</xsl:template>
<!-- or with namespace -->
<xsl:template match="//*[namespace-uri()='http://www.w3.org/1999/xhtml' and local-name()='i']">
<xsl:text>\textit{</xsl:text>
<xsl:apply-templates select="@*|node()"/>
<xsl:text>}</xsl:text>
</xsl:template>
<!-- assumes there is a copy happening like: -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
将类似的模板添加到XSL中,应该使其对输入中找到的每个 执行。
输出(当放入只复制HTML文档的XSL时)看起来像:
<!-- before -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>test</title>
</head>
<body>
<p>
<i>This is Only a Test</i>
</p>
</body>
</html>
<!-- after -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>test</title>
</head>
<body>
<p>
\textit{This is Only a Test}
</p>
</body>
</html>
如果你给我们更多,我会更新这个更具体。
编辑:基于OP代码的完整示例(最终提供)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:apply-templates select="one"/>
</xsl:template>
<xsl:template match="one">
<xsl:apply-templates select="two"/>
</xsl:template>
<xsl:template match="//i">
<xsl:text>\textit{</xsl:text>
<xsl:apply-templates select="@*|node()"/>
<xsl:text>}</xsl:text>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>