使用 XSLT 预处理 XML 中的 #ifdefs [英] Using XSLT to preprocess #ifdefs in XML

查看:67
本文介绍了使用 XSLT 预处理 XML 中的 #ifdefs的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这大概是使用 XSLT 作为 XML 预处理器的几乎副本处理器 但是由于该问题的 OP 没有发布完整的示例,尽管被要求,但对于不熟悉 XSLT 的任何人来说,这些回复都没有用.广泛的网络搜索也没有发现任何有用的东西 - XSLT 似乎非常缺乏文档,并且在网络上很少讨论.

This is presumably an almost carbon copy of Using XSLT as an XML pre-processor But as the OP of that question did not post a full example, despite being asked to, the replies are no use to anyone not familiar with XSLT. Neither have extensive web searches turned up anything helpful - XSLT seems remarkably poorly documented and little discussed on the Web.

无论如何...

我有一个 XML 文件,比如说 foo.xml,如下(显然已经大大简化了):

I have an XML file, say foo.xml, as follows (greatly simplified, obviously):

 <?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"块)

(C-style #ifdef changed to "ifdef" block in light of Ian Roberts's answer)

我想在linux上运行一个xsltproc命令,如下:

I want to run an xsltproc command on linux, as follows:

xsltproc --stringparam xmlver NEW_VERSION --nonet foo.xslt foo.xml

并使用以下 XSLT 文件 foo.xslt 来排除 #ifdef'ed 部分:

and have this use the following XSLT file, foo.xslt, to exclude the #ifdef'ed section:

<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"值.当然不能保证上面的内容是正确的;但是这个基本上我要问的是 - 如何以有效的方式将所有这些组合在一起?)

(I did use the replies to the question referenced above to construct this XSLT; but the missing ingredient is where/how to incorporate the "xmlver" value. Of course there is no guarantee it is correct in the above; but this essentially what I am asking - How is all this put together in a way that works?)

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

Any constructive replies will be greatly appreciated, and will doubtless be useful to many people with a similar requirement in the future; but please no tiresome, dogmatic "Why would you want to do that?" replies!

推荐答案

您提到的问题看起来像是基于 XML 结构,该结构将 XML 元素用于其 ifdef.在您的情况下,您的 #ifdef 行不是 XML 元素,因此您无法将它们与 XSLT 模板匹配.如果您需要对其进行其他 XML 感知处理,最好使用非 XML 工具(甚至可能是普通的 C 预处理器)来处理 ifdef 并将生成的 XML 提供给 XSLT.

The question you refer to looks like it's based on an XML structure that uses XML elements for its ifdefs. In your case your #ifdef lines are not XML elements, so you can't match them with an XSLT template. You'd be better off using a non-XML tool (possibly even the normal C pre-processor) to handle the ifdefs and feed the resulting XML to an XSLT if you need to do other XML-aware processing on it.

如果您愿意为 ifdef 使用真正的 XML 元素,如上一个问题所示:

If you're happy to use real XML elements for your ifdefs, as in the previous question:

<?xml version="1.0" encoding="UTF-8"?>
<main>
  <fee>blah</fee>

  <ifdef select="OLD_VERSION">
   <fi>blah blah</fi>
  </ifdef>

</main>

那么问题就变成了如何将 xmlver 命令行参数视为您想要包含的单个 ifdef,而不是作为加载一整套定义的文件位置(这就是上一个问题的工作方式).这要简单得多:

then the question becomes how to treat the xmlver command line parameter as the single ifdef that you want to include, rather than as the location of a file from which to load a whole set of defines (which is how the previous question worked). That is much simpler:

<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(它是 技术上不允许 XSLT 规范,并且 xsltproc 比我通常的测试工具更严格,夏兰).

My previous attempt at this used a <xsl:template match="ifdef[@select=$xmlver]">, which works in some processors but not in xsltproc (it is technically not allowed by the XSLT spec, and xsltproc is stricter than my usual test harness, Xalan).

这篇关于使用 XSLT 预处理 XML 中的 #ifdefs的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆