基于给定节点列表的 XSLT 过滤节点 [英] XSLT filter nodes based on given node list

查看:44
本文介绍了基于给定节点列表的 XSLT 过滤节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这可能已经在某处得到了回答,但我没有合适的词来搜索它:

This may have already be answered somewhere, but I do not have right words to search it :

假设我有包含城市列表的数据文件:

Lets say I have data file which has list of cities :

 <cities>
    <city abbr='A'>NameA</city>
    <city abbr='b'>NameB</city>
  </cities>

城市列表很长,我想根据缩写过滤城市

The cities list is long and I want to filter the cities based on abbr

[过滤数据]

   <skip>
     <abbr>A</abbr>
     <abbr>B</abbr>
   </skip>

如何使用此过滤器数据(以 xml 形式)跳过原始数据文件中的某些节点,特别是如何在 for-each 循环中使用,例如

How could I use the this filter data(in xml form) to skip some nodes from original data file , specifically how I can use in for-each loop e.g

 <xsl:template match="/">    
      <xsl:for-each select="not in skip list">
         ???
      </xsl:for-each>     
  </xsl:template>

我想在 XSLT 文件内部以 xml 格式使用过滤器数据,因为列表可能会变得太长.在 xslt 中包含文件的选项是什么?目前我正在使用 SAXON ……

I want to use the filter data internally within the XSLT file in the form of xml format as the list might get too long.What are the options to include the file within the xslt? Currently I am using SAXON sth like this.

java -jar /usr/local/liquibase/saxon/saxon9he.jar ./base/cities.xml ./templates/split_cities.xslt authorName=sakhunzai

这个例子是对原始数据的过度简化

This example is over simplification of original data

推荐答案

您使用 saxon 标签标记了您的问题,因此我假设您使用的是 xslt 2.0.

You tagged your question with saxon tag so I assume you are using xslt 2.0.

您可以创建一个变量来保存要跳过的值

You could make a variable holding values to be skipped

<xsl:variable name="skip">
    <abbr>A</abbr>
    <abbr>C</abbr>
</xsl:variable>

然后你可以根据这个变量测试节点的属性

Then you could test attribute of nodes against this variable

<xsl:apply-templates select="cities/city[not(@abbr = $skip/abbr)]" />

所以对于输入

<?xml version="1.0" encoding="UTF-8"?>
 <cities>
    <city abbr='A'>NameA1</city>
    <city abbr='B'>NameB1</city>
    <city abbr='C'>NameC1</city>
    <city abbr='A'>NameA2</city>
    <city abbr='B'>NameB2</city>
    <city abbr='C'>NameC2</city>
  </cities>

关注 xslt

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:variable name="skip">
        <abbr>A</abbr>
        <abbr>C</abbr>
    </xsl:variable>

    <xsl:template match="/">
        <cities>
            <xsl:apply-templates select="cities/city[not(@abbr = $skip/abbr)]" />
        </cities>
    </xsl:template>

    <xsl:template match="city">
        <xsl:copy-of select="." />
    </xsl:template>
</xsl:stylesheet>

产生输出

<?xml version="1.0" encoding="UTF-8"?>
<cities xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <city abbr="B">NameB1</city>
    <city abbr="B">NameB2</city>
</cities>

将过滤器存储在外部文件中是有意义的.让skip.xml成为这样一个结构文件

It makes sense to store filter in external file. Let skip.xml be such file with structure

<?xml version="1.0" encoding="UTF-8"?>
<skip>
    <abbr>A</abbr>
    <abbr>C</abbr>
</skip>

然后您可以通过以下方式更改变量声明

Then you can change variable declaration in following manner

<xsl:variable name="skip" select="document('path/to/skip.xml')/skip/abbr" />

其他事情可能保持不变.

Other thing might stay unchanged.

这篇关于基于给定节点列表的 XSLT 过滤节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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