这大概是 Using XSLT as an XML pre-processor 的几乎抄本。但由于该问题的 OP 没有发布完整的示例,尽管被要求这样做,但这些回复对于任何不熟悉 XSLT 的人来说都是没有用的。广泛的网络搜索也没有发现任何有用的信息 - XSLT 的文档似乎非常少,并且在网络上的讨论也很少。
无论如何...
我有一个 XML 文件,例如 foo.xml,如下所示(显然已大大简化):
<?xml version="1.0" encoding="UTF-8"?>
<main>
<fee>blah</fee>
<ifdef select="OLD_VERSION">
<fi>blah blah</fi>
</ifdef>
</main>
(根据 Ian Roberts 的回答,C 风格的 #ifdef 更改为“ifdef” block )
我想在 Linux 上运行 xsltproc 命令,如下所示:
xsltproc --stringparam xmlver NEW_VERSION --nonet foo.xslt foo.xml
并使用以下 XSLT 文件 foo.xslt 来排除 #ifdef'ed 部分:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" />
<xsl:param name="xmlver" required="yes"/>
<xsl:template match="node() | @*">
<xsl:copy><xsl:apply-templates select="node() | @*"/></xsl:copy>
</xsl:template>
<xsl:variable name="defines" select="document($xmlver)/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>
</xsl:stylesheet>
(我确实使用了对上面提到的问题的答复来构建这个 XSLT;但是缺少的成分是在哪里/如何合并“xmlver”值。当然不能保证上面的内容是正确的;但是这个本质上我要问的是——所有这些是如何以一种有效的方式组合在一起的?)
任何建设性的回复将不胜感激,并且无疑对将来有类似需求的许多人有用;但请不要提出令人厌烦的、教条式的“你为什么要这么做?”回复!
最佳答案
您提到的问题看起来像是基于 XML 结构,该结构使用 XML 元素作为其 ifdef。在你的情况下你的 #ifdef
行不是 XML 元素,因此您无法将它们与 XSLT 模板匹配。如果您需要对其进行其他 XML 感知处理,最好使用非 XML 工具(甚至可能是普通的 C 预处理器)来处理 ifdef 并将生成的 XML 提供给 XSLT。
如果您愿意在 ifdef 中使用真正的 XML 元素,如上一个问题:
<?xml version="1.0" encoding="UTF-8"?>
<main>
<fee>blah</fee>
<ifdef select="OLD_VERSION">
<fi>blah blah</fi>
</ifdef>
</main>
那么问题就变成了如何将 xmlver 命令行参数视为单个 ifdef
您想要包含的内容,而不是作为从中加载整组定义的文件的位置(这就是上一个问题的工作方式)。这要简单得多:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" />
<xsl:param name="xmlver" />
<xsl:template match="node() | @*">
<xsl:copy><xsl:apply-templates select="node() | @*"/></xsl:copy>
</xsl:template>
<xsl:template match="ifdef">
<!-- for the ifdef we want, include all its child elements, text nodes etc
but not its attributes, for other ifdefs do nothing -->
<xsl:if test="@select = $xmlver">
<xsl:apply-templates select="node()" />
</xsl:if>
</xsl:template>
</xsl:stylesheet>
我之前的尝试使用了 <xsl:template match="ifdef[@select=$xmlver]">
,它适用于某些处理器,但不适用于 xsltproc(它是 technically not allowed by the XSLT spec ,并且 xsltproc 比我常用的测试工具 Xalan 更严格)。
关于xml - 使用 XSLT 预处理 XML 中的 #ifdef,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12282611/