【问题标题】:Using XSLT as an XML pre-processor使用 XSLT 作为 XML 预处理器
【发布时间】:2011-08-26 22:54:36
【问题描述】:

这是我第一次用 XSLT 或 XML 做任何事情,所以请原谅。我发现 XSLT 网络文档非常简洁。

我有一个要处理的 XML 文件,以便根据输入的定义集选择性地删除内容。该行为应该类似于处理 ifdef 块的简单代码预处理器。

我已经想出了如何做到这一点,但“内容”变量等某些部分似乎不是处理这个问题的最佳方法。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="xml" />
  <xsl:param name="defines-uri" required="yes"/>

  <xsl:template match="* | @*">
  <xsl:copy><xsl:copy-of select="@*"/><xsl:apply-templates/></xsl:copy>
  </xsl:template>

  <xsl:template match="ifdef">
    <xsl:variable name="contents" select="child::node()"/>
    <xsl:variable name="defines" select="document($defines-uri)/defines"/>
    <xsl:variable name="val" select="@select"/>

    <xsl:for-each select="$defines">
      <xsl:if test="def=$val">
        <xsl:apply-templates select="$contents"/>
      </xsl:if>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

主要问题是在定义中找到匹配项时的应用模板。如果没有内容,我会在输出中得到不同程度的定义文档。

在不进行转换的情况下对 XML 进行预处理的最佳方法是什么?

【问题讨论】:

  • 一个示例 XML 文档和预期的输出会很有帮助。

标签: xml xslt preprocessor


【解决方案1】:

我已经想出了如何做到这一点,但“内容”变量等某些部分似乎不是处理这个问题的最佳方法。

嗯,基本上你做对了。不过,您仍然可以稍微改进一下:

<xsl:variable name="defines" select="document($defines-uri)/defines"/>

<xsl:template match="ifdef">
  <xsl:variable name="this" select="."/>

  <xsl:for-each select="$defines[def = $this/@select]">
    <xsl:apply-templates select="$this/node()" />
  </xsl:for-each>
</xsl:template>

&lt;xsl:for-each&gt; 更改上下文节点。其中,. 指的是被迭代的节点,而不是 &lt;xsl:template&gt; 匹配的节点。

这意味着您必须在变量中保留“外部”上下文,这是标准做法。

【讨论】:

    【解决方案2】:

    对于刚刚开始使用 XSLT XML 的人来说,你做得很好。

    这不是您问题的答案,但我只想说这可能是一个更安全的“默认复制”模板:

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

    您的作品得益于某个默认的内置模板。但是,当您添加更多模板时,您可能会遇到关于文本节点(或其他非元素)的奇怪行为,因为默认值的优先级较低。

    【讨论】:

    • +1 - 同意。还值得注意的是,OP 的 &lt;copy-of select="@*" /&gt; 实际上对更复杂的转换没有帮助。
    猜你喜欢
    • 1970-01-01
    • 2020-07-03
    • 1970-01-01
    • 2012-05-18
    • 2013-03-06
    • 2011-12-06
    • 1970-01-01
    • 2013-12-06
    • 2021-04-19
    相关资源
    最近更新 更多