子串模板匹配xslt

时间:2012-09-20 07:35:28

标签: xml templates xslt xslt-2.0

我现在已经挣扎了一段时间。我刚开始使用xslt,我的工作正常。尽可能使用模板,我试图阻止自己使用for循环。

我的问题是:我有许多名称相似的节点,唯一的区别是从1到(当前)5的后缀号。这些都应该转换为没有数字的节点。所以基本上,这就是我所拥有的:

<title1>some title</title1>
<some_other_nodes>....</some_other_nodes>
<title2>some title2</title2>
.
.
.
<title5>....</title5>

这就是我想要的:

<title>some title</title>
.
.
.
<title>some title2</title>
.
.
.
<title>....</title>

是否可以与模板进行子串匹配(仅匹配标题部分)?

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

对于表单titleN的元素,其中N是某个数字,请使用匹配条件,如...

(校正:)

<xsl:template match="*[starts-with(name(),'title')]
                      [number(substring(name(),6))=number(substring(name(),6))]">
  etc...

不那么通用,但又快又脏,如果你想特别标题1到标题5,你也可以考虑......

<xsl:template match="title1|title2|title3|title4|title5">

答案 1 :(得分:1)

这是一个真正的 XSLT 2.0解决方案,它涵盖了最复杂的案例,未被其他答案涵盖

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

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

 <xsl:template match="*[matches(name(), '^title.*?\d+$')]">
  <xsl:element name="{replace(name(), '^(title.*?)\d+$', '$1')}">
    <xsl:copy-of select="namespace::*"/>
    <xsl:apply-templates select="node()|@*"/>
  </xsl:element>
 </xsl:template>
</xsl:stylesheet>

将此转换应用于以下XML文档

<t>
    <title1>some title</title1>
    <some_other_nodes>....</some_other_nodes>
    <title2>some title2</title2> . . . 
    <title5>....</title5>
    <titleX253>Complex title</titleX253>
</t>

产生了想要的正确结果

<t>
      <title>some title</title>
      <some_other_nodes>....</some_other_nodes>
      <title>some title2</title> . . . 
    <title>....</title>
      <titleX>Complex title</titleX>
</t>

请注意元素

<titleX253>Complex title</titleX253>

应转换为

<titleX>Complex title</titleX>

这不是Sean Durkin的答案