草庐IT

xml - 意外 <xsl :apply-imports/> behavior

coder 2024-07-05 原文

我一直在努力找出如何最好地模块化我的 XSLT 样式表以促进重用。我突然想到使用 作为将特定于文档的属性引入标准标记转换的方法。这没有按我预期的方式工作,我什至无法开始理解这里发生的事情。这是样式表的简化版本:

<!-- main.xsl -->
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet  version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:fo="http://www.w3.org/1999/XSL/Format">

<xsl:import href="html-customizations.xsl"/>

<xsl:output method="xml"
   indent="yes"
   omit-xml-declaration="no"/>

<xsl:template match="para">
  <fo:block>
      <xsl:attribute name="space-after">1em</xsl:attribute>
      <xsl:apply-templates/>
  </fo:block>
</xsl:template>

<!-- =============== -->
<!-- Inline Elements -->
<!-- =============== -->

<xsl:template match="i">
  <fo:inline font-style="italic">
    <xsl:apply-imports/>
    <xsl:apply-templates/>
  </fo:inline>
</xsl:template>

<!-- ================ -->
<!--      Tables      -->
<!-- ================ -->

<xsl:template match="table">
  <fo:table>
    <xsl:apply-imports/>
    <xsl:apply-templates/>
  </fo:table>
</xsl:template>

<xsl:template  match="tr">
  <fo:table-row>
    <xsl:apply-imports/>
    <xsl:apply-templates/>
  </fo:table-row>
</xsl:template>

<xsl:template match="td | th">
  <fo:table-cell>
    <xsl:apply-imports/>
    <xsl:apply-templates/>
  </fo:table-cell>
</xsl:template>
</xsl:stylesheet>

导入的样式表:

<!-- html-customizations.xsl -->
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet  version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:fo="http://www.w3.org/1999/XSL/Format">

<xsl:template  match="td | th">
  <xsl:attribute name="hyphenate">true</xsl:attribute>
</xsl:template>

</xsl:stylesheet>

这是 XML 输入文件:

<!-- test.xml -->
<para>
  <table>
    <tr><td>Spongebob Squarepants, <i>Chair</i></td></tr>
    <tr><td>Patrick Starfish, <i>Vice Cchair</i></td></tr>
    <tr><td>Squidword, <i>Secretary</i></td></tr>
  </table>
</para>

$ xalan -o out.xml test.xml main.xsl

out.xml:
<?xml version="1.0" encoding="UTF-8"?>
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" space-after="1em">
  <fo:table>
    <fo:table-row>
<fo:table-cell hyphenate="true">Spongebob Squarepants, <fo:inline font-style="italic">ChairChair</fo:inline>
</fo:table-cell>
<fo:table-cell hyphenate="true">Spongebob Squarepants, <fo:inline font-style="italic">ChairChair</fo:inline>
</fo:table-cell>
</fo:table-row>
    <fo:table-row>
<fo:table-cell hyphenate="true">Patrick Starfish, <fo:inline font-style="italic">Vice CchairVice Cchair</fo:inline>
</fo:table-cell>
<fo:table-cell hyphenate="true">Patrick Starfish, <fo:inline font-style="italic">Vice CchairVice Cchair</fo:inline>
</fo:table-cell>
</fo:table-row>
    <fo:table-row>
<fo:table-cell hyphenate="true">Squidword, <fo:inline font-style="italic">SecretarySecretary</fo:inline>
</fo:table-cell>
<fo:table-cell hyphenate="true">Squidword, <fo:inline font-style="italic">SecretarySecretary</fo:inline>
</fo:table-cell>
</fo:table-row>

    <fo:table-row>
<fo:table-cell hyphenate="true">Spongebob Squarepants, <fo:inline font-style="italic">ChairChair</fo:inline>
...
...

如您所见,与包含 的模板匹配的元素的每个子元素都会重复!我包含了导入的样式表以说明我正在尝试做什么。如果我注释掉这个导入:

<!--
<xsl:import href="html-customizations.xsl"/>
-->

重复行为是一样的:

<?xml version="1.0" encoding="UTF-8"?>
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" space-after="1em">
  <fo:table>
    <fo:table-row>
<fo:table-cell>Spongebob Squarepants, <fo:inline font-style="italic">ChairChair</fo:inline>Spongebob Squarepants, <fo:inline font-style="italic">ChairChair</fo:inline>
</fo:table-cell>
<fo:table-cell>Spongebob Squarepants, <fo:inline font-style="italic">ChairChair</fo:inline>Spongebob Squarepants, <fo:inline font-style="italic">ChairChair</fo:inline>
</fo:table-cell>
</fo:table-row>
    <fo:table-row>
...
...

没有我试图从导入的样式表中添加的属性;即只是 处理指令的 存在 导致输出元素加倍。另请注意,这不仅仅是一个 xalan 问题——同样的事情也会发生在 Windows 7 上的 MSXML 上。

有什么想法吗?我指望这项工作,所以现在我正在努力想办法解决这个问题,让它工作。

顺便说一句,我对如何使用 的假设是基于 Michael Kay 书中的 xsl:import 部分给出的示例。如果有人知道解释我在上面看到的行为的引用资料,请分享。

最佳答案

我同意 apply-imports 的行为很难理解。问题是 apply-imports 总是 找到与当前节点匹配的模板,即使用户没有定义它。在这种情况下,默认 模板适用。

以下样式表有效:

XSLT 样式表

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet  version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:fo="http://www.w3.org/1999/XSL/Format">

    <xsl:import href="html-customizations.xsl"/>

    <xsl:output method="xml"
        indent="yes"
        omit-xml-declaration="no"/>

    <xsl:template match="para">
        <fo:block>
            <xsl:attribute name="space-after">1em</xsl:attribute>
            <xsl:apply-templates/>
        </fo:block>
    </xsl:template>

    <!-- =============== -->
    <!-- Inline Elements -->
    <!-- =============== -->

    <xsl:template match="i">
        <fo:inline font-style="italic">
            <xsl:apply-templates/>
        </fo:inline>
    </xsl:template>

    <!-- ================ -->
    <!--      Tables      -->
    <!-- ================ -->

    <xsl:template match="table">
        <fo:table>

            <xsl:apply-templates/>
        </fo:table>
    </xsl:template>

    <xsl:template  match="tr">
        <fo:table-row>

            <xsl:apply-templates/>
        </fo:table-row>
    </xsl:template>

    <xsl:template match="td | th">
        <fo:table-cell>
            <xsl:apply-imports/>
            <xsl:apply-templates/>
        </fo:table-cell>
    </xsl:template>
</xsl:stylesheet>

如您所见,我删除了两个 apply-imports 元素,只留下一个在 template/@match='td | 中的元素第一个。然后,输出将是

XML 输出

<?xml version="1.0" encoding="UTF-8"?>
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" space-after="1em">
    <fo:table>
        <fo:table-row>
         <fo:table-cell hyphenate="true">Spongebob Squarepants, <fo:inline font-style="italic">ChairChair</fo:inline>
         </fo:table-cell>
      </fo:table-row>
        <fo:table-row>
         <fo:table-cell hyphenate="true">Patrick Starfish, <fo:inline font-style="italic">Vice CchairVice Cchair</fo:inline>
         </fo:table-cell>
      </fo:table-row>
        <fo:table-row>
         <fo:table-cell hyphenate="true">Squidword, <fo:inline font-style="italic">SecretarySecretary</fo:inline>
         </fo:table-cell>
      </fo:table-row>
    </fo:table>
</fo:block>

到底发生了什么?

apply-imports 寻找一个模板

  • 匹配当前节点
  • 匹配当前模式
  • 在导入的样式表中

现在,关键是:这条指令将调用 built-in templates如果在导入的样式表中找不到这样的模板。在 tr 的情况下:

<xsl:template  match="tr">
  <fo:table-row>
    <xsl:apply-imports/>
    <xsl:apply-templates/>
  </fo:table-row>
</xsl:template>

元素节点的默认操作是遍历它并对它的内容应用模板,所以上面的代码片段实际上转化为

<xsl:template  match="tr">
  <fo:table-row>
    <xsl:apply-templates/>
    <xsl:apply-templates/>
  </fo:table-row>
</xsl:template>

这就是输出包含重复项的原因。我假设您现在也明白为什么注释掉 xsl:import 没有帮助,否则我很乐意详细说明。


由于您还要求提供引用,因此 在 Michael Kay 的 XSLT 2.0 和 XPath 2.0 程序员引用 中进行了解释,第 238 页。

关于xml - 意外 <xsl :apply-imports/> behavior,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29943838/

有关xml - 意外 <xsl :apply-imports/> behavior的更多相关文章

  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 - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  3. ruby-on-rails - rspec should have_select ('cars' , :options => ['volvo' , 'saab' ] 不工作 - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request

  4. ruby-on-rails - Nokogiri:使用 XPath 搜索 <div> - 2

    我使用Nokogiri(Rubygem)css搜索寻找某些在我的html里面。看起来Nokogiri的css搜索不喜欢正则表达式。我想切换到Nokogiri的xpath搜索,因为这似乎支持搜索字符串中的正则表达式。如何在xpath搜索中实现下面提到的(伪)css搜索?require'rubygems'require'nokogiri'value=Nokogiri::HTML.parse(ABBlaCD3"HTML_END#my_blockisgivenmy_bl="1"#my_eqcorrespondstothisregexmy_eq="\/[0-9]+\/"#FIXMEThefoll

  5. 微信小程序开发入门与实战(Behaviors使用) - 2

    @作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors    1、什么是behaviors    2、behaviors的工作方式    3、创建behavior    4、导入并使用behavior    5、behavior中所有可用的节点    6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors    1、什么是behaviorsbehaviors是小程序中,用于实现

  6. ruby-on-rails - 没有参数的 `<<`(小于两倍)是什么意思? - 2

    我在一个我想在formtasticGem中覆盖的方法中找到了这个。该方法如下所示:defto_htmlinput_wrappingdohidden_field_html是什么意思?在第三行做什么?我知道它对数组有什么作用,但在这里我不知道。 最佳答案 你可以这样读:hidden_field_htmllabel_with_nested_checkbox是连接到hidden_​​field_html末尾的参数-为了“清晰”,他们将其分成两行 关于ruby-on-rails-没有参数的`

  7. ruby-on-rails - 找不到 gem railties (>= 0.a) (Gem::GemNotFoundException) - 2

    我已经看到了一些其他的问题,尝试了他们的建议,但没有一个对我有用。我已经使用Rails大约一年了,刚刚开始一个新的Rails项目,突然遇到了问题。我卸载并尝试重新安装所有Ruby和Rails。Ruby很好,但Rails不行。当我输入railss时,我得到了can'tfindgemrailties。我当前的Ruby版本是ruby2.2.2p95(2015-04-13修订版50295)[x86_64-darwin15],尽管我一直在尝试通过rbenv设置ruby​​2.3.0。如果我尝试rails-v查看我正在运行的版本,我会得到同样的错误。我使用的是MacOSXElCapitan版本10

  8. Ruby - 如何处理子类意外覆盖父类(super class)私有(private)字段的问题? - 2

    假设您编写了一个类Sup,我决定将其扩展为SubSup。我不仅需要了解你发布的接口(interface),还需要了解你的私有(private)字段。见证这次失败:classSupdefinitialize@privateField="fromsup"enddefgetXreturn@privateFieldendendclassSub问题是,解决这个问题的正确方法是什么?看起来子类应该能够使用它想要的任何字段而不会弄乱父类(superclass)。编辑:equivalentexampleinJava返回"fromSup",这也是它应该产生的答案。 最佳答案

  9. ruby-on-rails - 连接字符串时如何在 <%=%> block 内输出 html_safe? - 2

    考虑一下:现在这些情况:#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2我需要用其他字符串输出URL。我如何保证&符号不会被转义?由于我无法控制的原因,我无法发送&。求助!把我的头发拉到这里:\编辑:为了澄清,我实际上有一个像这样的数组:@images=[{:id=>"fooid",:url=>"http://

  10. Ruby -> 写入二维数组 - 2

    我正在处理http://prepwork.appacademy.io/mini-curriculum/array/中概述的数组问题我正在尝试创建函数my_transpose,它接受一个矩阵并返回其转置。我对写入二维数组感到很困惑!这是一个代码片段,突出了我的困惑。rows=[[0,1,2],[3,4,5],[6,7,8]]columns=Array.new(3,Array.new(3))putscolumns.to_s#Outputisa3x3arrayfilledwithnilcolumns[0][0]=0putscolumns.to_s#Outputis[[0,nil,nil],[

随机推荐