【问题标题】:使用 XSLT 过滤 XML 文档的动态 XPath
【发布时间】:2022-01-17 17:45:54
【问题描述】:

我一直在搜索 StackOverflow 一段时间但没有成功。我的目标是过滤 Employee XML 文档。输入 XML 有大约 9000 名员工,并且我有多个目标系统,它们需要基于每个目标系统的不同选择标准的这些员工记录的子集。 样本输入:

<Employees>
  <Employee>
    <id>1</id>
    <name>Name1</name>
  </Employee>
  <Employee>
    <id>2</id>
    <name>Name2</name>
  </Employee>
  <Employee>
    <id>3</id>
    <name>Name3</name>
  </Employee>
  <Employee>
    <id>4</id>
    <name>Name4</name>
  </Employee>
</Employees>

输出应该具有相同的结构,但根据选择标准(XPATH)减少了节点。 如何将动态 XPath 传递给 XSLT 样式表并将过滤后的员工作为输出? 请注意完整的 Xpath 表达式以及过滤条件作为一个字符串传递。

期望的输出:

<Employees>
      <Employee>
        <id>2</id>
        <name>Name2</name>
      </Employee>
      <Employee>
        <id>3</id>
        <name>Name3</name>
      </Employee>
 </Employees>

【问题讨论】:

  • 维护根节点是可选的。根节点可以忽略,输出也可以是多个匹配选择条件的员工节点。
  • 在 XSLT 3 中使用静态参数和影子属性这很简单,但您需要使用 XSLT 3 处理器及其 API 或接口才能使用该功能。
  • 您可能会考虑在您的程序中仅使用 XPath 进行过滤,例如在 C# 中使用 XmlDocument.SelectNodes( "//your/dynamic/xapth[@filter=1]" )。然后在 XSL 中格式化结果。

标签: xml xslt xpath xslt-3.0


【解决方案1】:

对于 XSLT 3.0,xsl:evaluate 用于动态 XPath 评估。您可以将 XPath 接受为 xsl:param(显示为默认 XPath 值示例),然后对其进行评估。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
    <xsl:output indent="yes"/>
    
    <xsl:mode on-no-match="shallow-copy"/>
    
    <xsl:param name="path" select="'/Employees/Employee[number(id)[. gt 1 and . lt 4]]'" />
        
    <xsl:template match="Employees">
        <xsl:copy>
            <xsl:evaluate xpath="$path" context-item="."/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

【讨论】:

  • 这段代码只返回节点内的值,而不是作为 XML 输出。
  • 好吧,您没有提供所需输出的示例,因此很难猜出您想要什么。您可以通过将应用模板包装在某些元素中来使其格式良好的 XML 输出,您可以复制文档元素等。
  • 更新了所需的输出。评估函数是只返回值,还是与节点信息一起返回?
  • xsl:evaluate 将返回节点,您可以简单地在模板中返回,如果您不打算转换或过滤任何内容,则无需应用模板。我已经更新了解决方案。
  • 完美,谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-11
  • 1970-01-01
  • 2016-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-19
相关资源
最近更新 更多