草庐IT

带有内联 XSLT 的 XML

coder 2024-06-29 原文

我需要一个 XML 文件在安装后根据一些参数进行更改。

例如:

<?xml ...?>
<root xmlns="...">

  <!-- remove this element when PARAM_MODE=1 -->
  <sometag />

  <!-- remove this element when PARAM_MODE=2 -->
  <sometag2 />

  <someothertag />
</root>

最简单的方法是使用 XSLT 删除元素,但我希望将注释和 XSL 结合起来而不是重复。

有什么可以做到的吗?像这样:

<?xml ...?>
<root xmlns="..." xmlns:xsl="XSL_NAMESPACE">
  <!-- XSL to remove this element when PARAM_MODE=1 -->
  <xsl:remove the attribute if $PARAM_MODE=1 />
  <sometag />

  <!-- XSL to remove this element when PARAM_MODE=2 -->
  <xsl:remove the attribute if $PARAM_MODE=2 />
  <sometag2 />

  <someothertag />
</root>

最佳答案

这个样式表:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="...">
    <xsl:param name="PARAM_MODE" select="1"/>
    <xsl:template match="@*|node()" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="my:sometag">
        <xsl:if test="$PARAM_MODE!=1">
            <xsl:call-template name="identity"/>
        </xsl:if>
    </xsl:template>
    <xsl:template match="my:sometag2">
        <xsl:if test="$PARAM_MODE!=2">
            <xsl:call-template name="identity"/>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

有了这个输入:

<root xmlns="...">
    <!-- remove this element when PARAM_MODE=1 -->
    <sometag />
    <!-- remove this element when PARAM_MODE=2 -->
    <sometag2 />
    <someothertag />
</root>

输出:

<root xmlns="...">
    <!-- remove this element when PARAM_MODE=1 -->
    <!-- remove this element when PARAM_MODE=2 -->
    <sometag2></sometag2>
    <someothertag></someothertag>
</root>

请注意,如果您想要简化语法,来自http://www.w3.org/TR/xslt#result-element-stylesheet :

A simplified syntax is allowed for stylesheets that consist of only a single template for the root node. The stylesheet may consist of just a literal result element (see 7.1.1 Literal Result Elements). Such a stylesheet is equivalent to a stylesheet with an xsl:stylesheet element containing a template rule containing the literal result element; the template rule has a match pattern of /.

因此,您可以添加元素,但不能删除它们。

编辑:简化语法的反向逻辑。

假设这个样式表有... test.xsl URI:

<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<root 
 xmlns="..." 
 xmlns:my="..." 
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
 xsl:version="1.0">
    <PARAM_MODE>1</PARAM_MODE>
    <!-- remove this element when PARAM_MODE=1 -->
    <xsl:if test="document('')/my:root/my:PARAM_MODE!=1">
        <sometag />
    </xsl:if>
    <!-- remove this element when PARAM_MODE=2 -->
    <xsl:if test="document('')/my:root/my:PARAM_MODE!=2">
        <sometag2 />
    </xsl:if>
    <someothertag />
</root>

Runnig 以自身作为输入(我用 PI 强调这一点。另外,这使得 fn:document() 变得多余...),它输出:

<root xmlns="..." xmlns:my="...">
    <PARAM_MODE>1</PARAM_MODE>
    <sometag2 />
    <someothertag />
</root>

最后,一个评论驱动的样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:param name="PARAM_MODE" select="1"/>
    <xsl:template match="@*|node()" name="identity">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*[preceding-sibling::node()[1]
                            /self::comment()[starts-with(.,' remove ')]]">
        <xsl:if test="$PARAM_MODE != substring-after(
                                        preceding-sibling::comment()[1],
                                        'PARAM_MODE=')">
            <xsl:call-template name="identity"/>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

输出:

<root xmlns="...">
    <!-- remove this element when PARAM_MODE=1 -->
    <!-- remove this element when PARAM_MODE=2 -->
    <sometag2></sometag2>
    <someothertag></someothertag>
</root>

关于带有内联 XSLT 的 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4034204/

有关带有内联 XSLT 的 XML的更多相关文章

  1. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  2. ruby-on-rails - 带有 Zeus 的 RSpec 3.1,我应该在 spec_helper 中要求 'rspec/rails' 吗? - 2

    使用rspec-rails3.0+,测试设置分为spec_helper和rails_helper我注意到生成的spec_helper不需要'rspec/rails'。这会导致zeus崩溃:spec_helper.rb:5:in`':undefinedmethod`configure'forRSpec:Module(NoMethodError)对thisissue最常见的回应是需要'rspec/rails'。但这是否会破坏仅使用spec_helper拆分rails规范和PORO规范的全部目的?或者这无关紧要,因为Zeus无论如何都会预加载Rails?我应该在我的spec_helper中做

  3. Ruby:如何使用带有散列的 'send' 方法调用方法? - 2

    假设我有一个类A,里面有一些方法。假设stringmethodName是这些方法之一,我已经知道我想给它什么参数。它们在散列中{'param1'=>value1,'param2'=>value2}所以我有:params={'param1'=>value1,'param2'=>value2}a=A.new()a.send(methodName,value1,value2)#callmethodnamewithbothparams我希望能够通过传递我的哈希以某种方式调用该方法。这可能吗? 最佳答案 确保methodName是一个符号,而

  4. ruby-on-rails - 带有 Pry 的 Rails 控制台 - 2

    当我进入Rails控制台时,我已将pry设置为加载代替irb。我找不到该页面或不记得如何将其恢复为默认行为,因为它似乎干扰了我的Rubymine调试器。有什么建议吗? 最佳答案 我刚发现问题,pry-railsgem。忘记了它的目的是让“railsconsole”打开pry。 关于ruby-on-rails-带有Pry的Rails控制台,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/question

  5. 带有 attr_accessor 的类上的 Ruby instance_eval - 2

    我了解instance_eval和class_eval之间的基本区别。我在玩弄时发现的是一些涉及attr_accessor的奇怪东西。这是一个例子:A=Class.newA.class_eval{attr_accessor:x}a=A.newa.x="x"a.x=>"x"#...expectedA.instance_eval{attr_accessor:y}A.y="y"=>NoMethodError:undefinedmethod`y='forA:Classa.y="y"=>"y"#WHATTT?这是怎么回事:instance_eval没有访问我们的A类(对象)然后它实际上将它添加到

  6. ruby-on-rails - Rails 渲染带有驼峰命名法的 json 对象 - 2

    我在一个简单的RailsAPI中有以下Controller代码:classApi::V1::AccountsControllerehead:not_foundendendend问题在于,生成的json具有以下格式:{id:2,name:'Simpleaccount',cash_flows:[{id:1,amount:34.3,description:'simpledescription'},{id:2,amount:1.12,description:'otherdescription'}]}我需要我生成的json是camelCase('cashFlows'而不是'cash_flows'

  7. ruby-on-rails - 在 Ruby 或 Rails 中,hash.merge({ :order => 'asc' }) can return a new hash with a new key. 什么可以返回带有已删除键的新散列? - 2

    在Ruby(或Rails)中,我们可以做到new_params=params.merge({:order=>'asc'})现在new_params是一个带有添加键:order的散列。但是是否有一行可以返回带有已删除key的散列?线路new_params=params.delete(:order)不会工作,因为delete方法返回值,仅此而已。我们必须分3步完成吗?tmp_params=paramstmp_params.delete(:order)returntmp_params有没有更好的方法?因为我想做一个new_params=(params[:order].blank?||para

  8. ruby-on-rails - 如何在 Rails 3 中禁用 XML 解析 - 2

    我想禁用HTTP参数的自动XML解析。但我发现命令仅适用于Rails2.x,它们都不适用于3.0:config.action_controller.param_parsers.deleteMime::XML(application.rb)ActionController::Base.param_parsers.deleteMime::XMLRails3.0中的等价物是什么? 最佳答案 根据CVE-2013-0156的最新安全公告你可以将它用于Rails3.0。3.1和3.2ActionDispatch::ParamsParser::

  9. ruby - 如何使用 Nokogiri::XML::Builder 生成动态标签? - 2

    我正在遍历数组中的一组标签名称,我想使用构建器打印每个标签名称,而不是求助于“我认为:builder=Nokogiri::XML::Builder.newdo|xml|fortagintagsxml.tag!tag,somevalendend会这样做,但它只是创建名称为“tag”的标签,并将标签变量作为元素的文本值。有人可以帮忙吗?这个看起来应该比较简单,我刚刚在搜索引擎上找不到答案。我可能没有以正确的方式提问。 最佳答案 尝试以下操作。如果我没记错的话,我添加了一个根节点,因为Nokogiri需要一个。builder=Nokogi

  10. ruby - 如何让 Nokogiri 解析并返回 XML 文档? - 2

    这是一些奇怪的例子:#!/usr/bin/rubyrequire'rubygems'require'open-uri'require'nokogiri'print"withoutread:",Nokogiri(open('http://weblog.rubyonrails.org/')).class,"\n"print"withread:",Nokogiri(open('http://weblog.rubyonrails.org/').read).class,"\n"运行此返回:withoutread:Nokogiri::XML::Documentwithread:Nokogiri::

随机推荐