XSLT过滤节点基于给定的节点列表

时间:2013-08-16 06:55:49

标签: xml xslt saxon

这可能已在某处得到解答,但我没有正确的词语来搜索它:

假设我有数据文件,其中包含城市列表:

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

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

[过滤数据]

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

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

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

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

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

此示例简化了原始数据

1 个答案:

答案 0 :(得分:4)

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

您可以设置一个变量保持值被跳过

<xsl:variable name="skip">
    <abbr>A</abbr>
    <abbr>C</abbr>
</xsl: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成为结构

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

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

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

其他事情可能保持不变。