2

这大概是使用 XSLT 作为 XML 预处理器的几乎复本但是由于该问题的 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”值。当然不能保证它在上面是正确的;但这基本上是我我在问 - 所有这些是如何以一种有效的方式组合在一起的?)

任何建设性的答复将不胜感激,并且无疑会对将来有类似要求的许多人有用;但请不要烦人,教条“你为什么要这样做?” 回复!

4

3 回答 3

1

您提到的问题看起来像是基于使用 XML 元素作为其 ifdef 的 XML 结构。在您的情况下,您的#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>

我之前的尝试使用了 a <xsl:template match="ifdef[@select=$xmlver]">,它适用于某些处理器,但不适用于 xsltproc(从技术上讲,XSLT 规范不允许这样做,而且 xsltproc 比我通常的测试工具 Xalan 更严格)。

于 2012-09-05T13:53:20.007 回答
1

建议:代替 xsltproc,你可以只使用m4吗?

<?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>
于 2012-09-05T14:09:46.607 回答
0

我想从你的一般方法开始:

这些回复对不熟悉 XSLT 的任何人都没有用。广泛的网络搜索也没有发现任何有用的东西——XSLT 似乎记录得非常少,并且在网络上很少讨论。

这基本上告诉我们您正在尝试使用您不熟悉的语言编写程序,并且您正在尝试通过谷歌搜索来查找有关该语言的信息。这是一个好的学习策略吗?

我会认为您的问题是点击次数过多而不是过少,例如“XSLT 教程”提供了 2,300,000 次点击。顶级的都值得一读。将其描述为“记录不充分且很少讨论”似乎很奇怪。

就个人而言,如果我要开始使用一种新语言进行编程,我总是从阅读有关该主题的书开始。在线材料很少像教科书那样经过精心设计、编写和审查。当然我会这么说,因为我是最流行的 XSLT 参考书之一的作者,但我认为这是真的。

现在,我能帮你解决你的问题吗?不是真的,我很遗憾。有些人使用经过测试的有效代码来回答这个论坛上的问题,您可以在不理解的情况下使用这些代码。我没有:我只是将人们指向正确的方向;我不会用你不懂的语言给你代码片段。在这种情况下,为您指明正确的方向意味着告诉您在尝试使用该语言之前先学习它。

于 2012-09-05T16:25:24.697 回答