在XSLT中匹配以空格分隔的值

时间:2012-12-25 20:29:37

标签: xslt xslt-1.0

项目的属性在@properties属性中以空格分隔的术语列出。还有一个主要的属性列表。

<t>

   <items>
     <item id='a' properties='red little' />
     <item id='b' properties='big strong heavy' />
     <item id='c' properties='blue heavy' >
   </items>

   <properties>
     <property id='red' />
     <property id='little' />
     <property id='blue' />
   </properties>

</t>

我的问题:使用XLST 1.0,为模板编写匹配属性,该属性将匹配属性主列表中至少有一个属性的所有项目。

项目a和c匹配。项目b不会。

这是XSLT 1.0,所以我不能使用str:split。也许有关键和contains()的东西?

3 个答案:

答案 0 :(得分:1)

你也可以使用<xsl:if>吗?

<xsl:template match="item">
    <xsl:if test="/t/properties/property[contains(concat(' ', current()/@properties, ' '), concat(' ', @id, ' '))]">
        ...
    </xsl:if>
</xsl:template>

不幸的是,current()无法在match属性中使用。

答案 1 :(得分:1)

使用Michael Liu的XPath表达式,您还可以构造一个允许您匹配正确元素的键:

<xsl:key name="inMaster" match="item" use="
    substring(
      '1',
      1,
      string-length(
        /t/properties/property[
          contains(concat(' ', current()/@properties, ' '), concat(' ', @id, ' '))
        ]/@id
      )
    )"/>

<!-- The following template matches the wanted item elements -->
<xsl:template match="key('inMaster','1')">
  ...
</xsl:template>

我们使用substring()函数将匹配的<item>元素与字符串"1"相关联。所有不匹配的item元素都与空字符串相关联,因为没有匹配的“master”属性,因此没有id属性,因此string-length()为0,因此我们提取了一个子字符串长度为0(即空字符串)。

答案 2 :(得分:1)

<强>予。使用密钥和current()的另一种解决方案:):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:key name="kItemByProp" match="item"
  use="boolean(/*/properties/property/@id
                 [contains(concat(' ', current()/@properties, ' '),
                           .)]
              )"/>

 <xsl:template match=
  "item[count(.| key('kItemByProp', 'true'))
       =
        count(key('kItemByProp', 'true'))
        ]
  ">
  <xsl:copy-of select="."/>
 </xsl:template>
</xsl:stylesheet>

在提供的XML文档上应用此转换时:

<t>
    <items>
        <item id='a' properties='red little' />
        <item id='b' properties='big strong heavy' />
        <item id='c' properties='blue heavy' />
    </items>
    <properties>
        <property id='red' />
        <property id='little' />
        <property id='blue' />
    </properties>
</t>

产生了想要的正确结果:

<item id="a" properties="red little"/>
<item id="c" properties="blue heavy"/>

<强> II。没有键,但条件指令作为模板体中的最外层:

 <xsl:template match="item">
  <xsl:if test=
  "/*/properties/*/@id
        [contains(concat(' ', current()/@properties, ' '), .)]">
    <!-- Your processing here -->
  </xsl:if>
 </xsl:template>

这是一个完整的转型:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="item">
  <xsl:if test=
  "/*/properties/*/@id
        [contains(concat(' ', current()/@properties, ' '), .)]">
    <xsl:copy-of select="."/>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于同一XML文档(上图)时,会产生相同的正确结果

<item id="a" properties="red little"/>
<item id="c" properties="blue heavy"/>