xslt模式匹配转换

时间:2010-09-10 15:12:06

标签: xslt

如何使用XSLT转换以下XML:

<root>
    <list>
        <item label="21(1)">some text</item>
        <item label="(2)">some text</item>
    </list>
    <list>
        <item label="a">some text</item>
        <item label="b">some text</item>
    </list>
</root>

到此:

<root>
    <list label="21">
        <item label="(1)">some text</item>
        <item label="(2)">some text</item>
    </list>
    <list>
        <item label="a">some text</item>
        <item label="b">some text</item>
    </list>
</root>

因此,如果第一个label的{​​{1}}属性的括号前面有一个数字,那么该数字需要作为父项的item属性的值label项。

匹配属性的模式类似于:

list

4 个答案:

答案 0 :(得分:1)

你可以使用xslt函数substring-before来获取'('

之前的子字符串

答案 1 :(得分:1)

如Nikolaus所述,您可以使用substring-beforesubstring-after XPath函数。 XSL转换示例如下所示:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="list">
    <list>
      <xsl:variable name="prefix" select="substring-before(./item/@label, '(')" />
      <xsl:if test="$prefix != '' and number($prefix)">
        <xsl:attribute name="label">
          <xsl:value-of select="substring-before(./item/@label, '(')"/>
        </xsl:attribute>
      </xsl:if>
      <xsl:apply-templates />
    </list>
  </xsl:template>

  <xsl:template match="item">
    <item>
      <xsl:attribute name="label">
        <xsl:variable name="prefix" select="substring-before(@label, '(')" />
        <xsl:choose>
          <xsl:when test="$prefix != '' and number($prefix)">
            <xsl:value-of select="concat('(', substring-after(@label, '('))"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="@label"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>
      <xsl:apply-templates />
    </item>
  </xsl:template>
</xsl:stylesheet>

答案 2 :(得分:1)

此样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:strip-space elements="*"/>
 <xsl:template match="node()|@*" name="identity">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
 </xsl:template>
 <xsl:template match="item[1][boolean(number(substring-before(@label,'(')))]">
    <xsl:attribute name="label">
        <xsl:value-of select="substring-before(@label,'(')"/>
    </xsl:attribute>
    <xsl:call-template name="identity"/>
 </xsl:template>
 <xsl:template match="item[1]/@label[boolean(number(substring-before(.,'(')))]">
    <xsl:attribute name="label">
        <xsl:value-of select="concat('(',substring-after(.,'('))"/>
    </xsl:attribute>
 </xsl:template>
</xsl:stylesheet>

输出:

<root>
    <list label="21">
        <item label="(1)">some text</item>
        <item label="(2)">some text</item>
    </list>
    <list>
        <item label="a">some text</item>
        <item label="b">some text</item>
    </list>
</root>

编辑:紧凑谓词。

编辑2 :测试编号之前 parentesis。明显只剥离空白节点。

答案 3 :(得分:0)

此XSLT 1.0转换

<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="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match=
  "list[number(substring-before(item[1]/@label, '('))
       =
       number(substring-before(item[1]/@label, '('))
       ]">
  <list label="{substring-before(item[1]/@label, '(')}">
    <xsl:apply-templates select="node()|@*"/>
  </list>
 </xsl:template>

 <xsl:template match=
   "item[1]/@label[number(substring-before(., '('))
           =
           number(substring-before(., '('))
           ]">
   <xsl:attribute name="label">
    <xsl:value-of select="concat('(',substring-after(.,'('))"/>
   </xsl:attribute>
 </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档

<root>
    <list>
        <item label="21(1)">some text</item>
        <item label="(2)">some text</item>
    </list>
    <list>
        <item label="a">some text</item>
        <item label="b">some text</item>
    </list>
</root>

生成想要的正确结果

<root>
    <list label="21">
        <item label="(1)">some text</item>
        <item label="(2)">some text</item>
    </list>
    <list>
        <item label="a">some text</item>
        <item label="b">some text</item>
    </list>
</root>