【问题标题】:In XSLT, is it possible to keep track of the path and use it dynamically?在 XSLT 中,是否可以跟踪路径并动态使用它?
【发布时间】:2013-05-22 09:28:56
【问题描述】:

昨天我问a question 关于从 XSLT 动态加载外部 XML 的问题。它已被回答,但现在我有另一个问题。如果您阅读该问题,您将在第三级看到<include ref="/path/to/some.xml" />。如果<include> 出现的级别不同怎么办?

有没有办法动态选择从 XML 中提取与原始文件中相同级别的节点?

编辑: 明确一点:我说的是 XML 中的“元素路径”(XML 中包含元素的位置),而不是文件路径。

合并.xslt:

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

  <xsl:output indent="yes" method="xml" encoding="utf-8"
    omit-xml-declaration="yes" />

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="include">
      <!-- the depth of the extraction path (fruit/*/*/*... etc) should
           be based on the position of the matched <include> element -->
      <xsl:apply-templates select="document(@ref)/fruit/*/*/*"/>
  </xsl:template>
</xsl:stylesheet>

水果.xml:

<fruit>
  <local>
    <apples>
      <include ref="apples.xml" />
    </apples>
  </local>
  <exotic>
    <bananas>
      <deeperlevel>
        <include ref="bananas.xml" />
      </deeperlevel>
    </bananas>
    <oranges>
      <include ref="oranges.xml" />
    </oranges>
  </exotic>
</fruit>

香蕉.xml:

<fruit>
  <exotic>
    <bananas>
      <deeperlevel>
        <banana type="chiquita" color="yellow" />
        <banana type="generic" color="yellow" />
      </deeperlevel>
    </bananas>
  </exotic>
</fruit>

结果:

<fruit>
  <local>
    <apples>
      <apple type="jonagold" color="red"/><apple type="granny-smith" color="green"/>
    </apples>
  </local>
  <exotic>
    <bananas>
      <deeperlevel>
        <deeperlevel> <!-- I don't want the second <deeperlevel> here, instead
                           <bananas .../> should be extracted, right after the
                           first <deeperlevel> -->
          <banana type="chiquita" color="yellow"/>
          <banana type="generic" color="yellow"/>
        </deeperlevel>
      </deeperlevel>
    </bananas>
    <oranges>
      <orange type="juice-orange" color="orange"/><orange type="red-orange" color="red"/>
    </oranges>
  </exotic>
</fruit>

【问题讨论】:

  • 您是指ref 属性值(即/path/to/some.xml)中提到级别时的步数吗?还是您在谈论include 元素的位置?在后一种情况下,建议的解决方案应该可以工作,它只匹配任何include 元素,而与它出现的嵌套级别无关。您可能想要发布一个新的 XML 输入示例以及您想要向我们解释哪些附加要求的结果你面对。
  • 我编辑了我的问题,它是关于从外部 XML 文档中提取的元素的选择,它们已经在输出 XML 中的正确位置结束。

标签: xslt dynamic path


【解决方案1】:

我找到了解决问题的方法。恕我直言,这不是很好,因为它是一个“eval”类型的解决方案,但它确实有效。我将this question 的答案中的第三条建议应用于我的问题,即动态 XPath 评估扩展 (dyn:evaluate())。幸运的是,libxslt 库中的 xsltproc 工具(通过 macports 安装,版本 1.1.27)支持它。

我打算暂时搁置这个问题,也许有人有更好的解决方案。

XSLT:

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:dyn="http://exslt.org/dynamic"
  extension-element-prefixes="dyn">

  <xsl:output indent="yes" method="xml" encoding="utf-8"
    omit-xml-declaration="yes" />

  <xsl:template match="@*|node()">
    <xsl:param name="depth" select="'/*'" />
    <xsl:copy>
      <xsl:apply-templates select="@*|node()">
        <xsl:with-param name="depth" select="concat($depth, '/*')" />
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="include">
    <xsl:param name="depth" />
    <xsl:apply-templates select="dyn:evaluate(concat('document(@ref)', $depth))">
      <xsl:with-param name="depth" select="$depth" />
    </xsl:apply-templates>
  </xsl:template>

</xsl:stylesheet>

【讨论】:

    猜你喜欢
    • 2014-07-18
    • 1970-01-01
    • 2020-05-15
    • 2011-01-11
    • 2020-11-19
    • 2022-01-17
    • 1970-01-01
    • 2020-04-28
    • 1970-01-01
    相关资源
    最近更新 更多