这可能是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”块)
我想在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”值。当然不能保证它在上面是正确的;但是这个基本上我要问的是 - 这一切如何以一种有效的方式组合在一起?)
任何建设性的回复都将受到高度赞赏,并且无疑对将来有类似要求的许多人有用;但请不要厌倦,教条“你为什么要那样做?”回复!
答案 0 :(得分:1)
您提到的问题看起来像是基于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更严格。
答案 1 :(得分:1)
建议:您可以使用m4吗?
代替xsltproc<?xml version="1.0" encoding="UTF-8"?>
<main>
<fee>blah</fee>
ifdef(`X',`
<fi>blah blah</fi>
')
</main>
$ m4 jeter.xml
<?xml version="1.0" encoding="UTF-8"?>
<main>
<fee>blah</fee>
</main>
$ m4 -DX jeter.xml
<?xml version="1.0" encoding="UTF-8"?>
<main>
<fee>blah</fee>
<fi>blah blah</fi>
</main>
答案 2 :(得分:0)
我想从你的一般方法开始:
回复对任何不熟悉XSLT的人都没用。也没有 广泛的网络搜索出现了任何有用的东西 - XSLT似乎 在网上很少记录和讨论很少。
这基本上告诉我们您正在尝试用您不熟悉的语言编写程序,并且您正试图通过Google搜索来查找有关该语言的信息。这是一个很好的学习策略吗?
我原以为你的问题是点击次数太多而不是太少,例如“XSLT教程”给出了2,300,000次点击。最重要的都值得一读。将其描述为“记录不清,很少讨论”似乎很奇怪。
就个人而言,如果我要开始用新语言编程,我总是先阅读一本关于这个主题的书。在线资料很少像教科书一样经过精心设计,编写和审核。当然我会说,因为我是最流行的XSLT参考书之一的作者,但我认为这是真的。
现在,我可以帮您解决问题吗?不是,我很遗憾。有些人使用经过测试的代码回复此论坛上的问题,您可以在不理解的情况下使用这些代码。我没有:我只是指出人们正确的方向;而且我不打算用你不懂的语言给你代码片段。在这种情况下,指向正确的方向意味着在尝试使用之前告诉您学习该语言。