如何忽略 XSLT 模板中的前 n 个表格

问题描述 投票:0回答:1

情况

在我的 XML 文件中,我可以放心地在标签内显示代码

<code>
。但是我的XML文档的缩进和
<code>
部分里面的表格有冲突。

最小的工作示例

XML 文件
        <article>
            <code lang="c">
            #include &lt;stdio.h&gt;
            int main() {
                // printf() displays the string inside quotation
                printf("Hello, World!");
                return 0;
            }
            </code>
        </article>
XSLT 的和平
    <xsl:template match="code">
        <pre><xsl:value-of select="."/></pre>
    </xsl:template>
预期的 HTML 渲染
<pre>   #include &lt;stdio.h&gt;
    int main() {
    // printf() displays the string inside quotation
    printf("Hello, World!");
    return 0;
}</pre>

说明

如您所见,目标是忽略标签内的n第一个制表和n最后一个制表(如果有),当n等于开始标签

<code>
之前的制表数。还要忽略第一个新行和最后一个新行(在结束
</code>
标签之前的表格之前)。

更多解释

According to @michael.hor257k suggestion to bring more clarifications,换句话说,XSLT样式表应该像这样对待上面显示的XML

<code>
部分:

        <article>
            <code lang="c">#include &lt;stdio.h&gt;
int main() {
    // printf() displays the string inside quotation
    printf("Hello, World!");
    return 0;
}</code>
        </article>

如您所见,属于 XML 缩进的选项卡不应包含在最终的 HTML

<pre>
标记中。

以更图形化的方式,我们可以说在处理过程中应忽略与下面注释的选项卡相对应的选项卡:

        <article>
            <code lang="c"><!--
         -->#include &lt;stdio.h&gt;
<!--     -->int main() {
<!--     -->    // printf() displays the string inside quotation
<!--     -->    printf("Hello, World!");
<!--     -->    return 0;
<!--     -->}<!--
         --></code>
        </article>

这个空格、制表符和新行对应于 XML 缩进,而不是内部 C 代码缩进。

结论——问题

那么,在我的 XSLT 中是否可以解析开始

<code>
标记之前的选项卡数量,以便从每个内容行的开头删除它们?

xml xslt indentation pre
1个回答
0
投票

尝试类似的东西:

XSLT 1.0 + EXSLT

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:str="http://exslt.org/strings"
extension-element-prefixes="str">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="code">
    <xsl:variable name="indent" select="substring-after(preceding-sibling::text(), '&#10;')" />
    <pre>
        <xsl:for-each select="str:tokenize(., '&#10;')[normalize-space()]">
            <xsl:value-of select="substring-after(., $indent)"/>
            <xsl:if test="position()!=last()">
                <xsl:text>&#10;</xsl:text>
            </xsl:if>
        </xsl:for-each>
    </pre>
</xsl:template>

</xsl:stylesheet>

请注意,这里有一些假设您的示例满足,但其他情况可能不满足。

© www.soinside.com 2019 - 2024. All rights reserved.