XSLT问题:属性值的正则表达式

时间:2018-10-04 13:41:21

标签: regex xml xslt

考虑以下XML:

   
<?xml-stylesheet type="text/xsl" href="eclas.xsl"?>

  <collection>
    <record>
      <datafield tag="150">
        <subfield code="a">Abandon des études</subfield><!--accepted FR-->
        <subfield code="9">fre</subfield>
      </datafield>
      <datafield tag="150">
        <subfield code="a">Student drop-out</subfield><!--accepted EN-->
        <subfield code="9">eng</subfield>
      </datafield>
      <datafield tag="450">
        <subfield code="a">Décrochage scolaire</subfield><!-- NOT accepted term FR-->
        <subfield code="9">fre</subfield>
      </datafield>
      <datafield tag="450">
        <subfield code="a">Abandon scolaire</subfield><!-- NOT accepted term FR-->
        <subfield code="9">fre</subfield>
      </datafield>
      <datafield tag="450">
        <subfield code="a">Abandon de la scolarité</subfield><!-- NOT preferred term FR-->
        <subfield code="9">fre</subfield>
      </datafield>
    </record>
    <record>
      <datafield tag="151">
        <subfield code="a">Egypte</subfield>
        <subfield code="9">fre</subfield>
      </datafield>
      <datafield tag="151">
        <subfield code="a">Egypt</subfield>
        <subfield code="9">eng</subfield>
      </datafield>
      <datafield tag="451">
        <subfield code="a">République arabe d&apos;Egypte</subfield>
        <subfield code="9">fre</subfield>
      </datafield>
      <datafield tag="451">
        <subfield code="a">République arabe unie</subfield>
        <subfield code="9">fre</subfield>
      </datafield>
      <datafield tag="451">
        <subfield code="a">United Arab Republic</subfield>
        <subfield code="9">eng</subfield>
      </datafield>
    </record>
</collection>

这是来自大型词库的样本。 我的正则表达式需要帮助,可以在150或151和450或451之间进行选择。

这是我遇到的xslt代码:

<xsl:for-each select="datafield[contains(@tag, '150|151' )]">
...
</xsl:for-each>

我试图遍历具有150或151作为值的数据字段元素。 我的正则表达式似乎无效。我已经尝试了几项都无济于事。

3 个答案:

答案 0 :(得分:1)

contains()将字符串而不是正则表达式作为第二个参数,因此您的代码正在寻找字符串150|151。您不能在XSLT 1.0中执行正则表达式。但是,使用choose()函数可以执行多个contains()。有关更多信息,请参见this问题。

答案 1 :(得分:0)

contains函数不使用正则表达式作为第二个参数,只是它检查的简单字符串是否在第一个字符串中。您应该使用matches ...

 <xsl:for-each select="datafield[matches(@tag, '^150$|^151$')]">

或者稍微好一点...

<xsl:for-each select="datafield[matches(@tag, '^(150|151)$')]">

例如,请注意多余的符号以防止匹配“ 1500”。

但是,matches仅是XSLT 2.0,而对<?xml-stylesheet的使用表明您正在浏览器中进行转换,实际上它只是XSLT 1.0。如果是这种情况,那么您可以花一点功夫使用contains

<xsl:for-each select="datafield[contains('|150|151|', concat('|', @tag, '|') )]">

例如,再次使用|是为了防止1500被盗。

答案 2 :(得分:0)

您要匹配以下4个字符串之一: 150 151 450 451 。请注意:

  • 第一个字符为14
  • 第二个字符始终为5
  • 最后一个字符为01

因此所有匹配的正则表达式为^[14]5[01]$

我放置了^$锚以防止匹配这样的字符串 作为较长文本的一部分(例如 31508 )。

因此在 XSLT 2.0 中,您可以编写:

<xsl:for-each select="datafield[matches(@tag, '^[14]5[01]$')]">