2012-09-20 89 views
2

我已经挣扎了一段时间了。我刚开始使用xslt,并且我的工作很好。尽可能使用模板,我尽量避免使用for循环。子字符串模板匹配xslt

我的问题是这样的:我有一些具有相似名称的节点,唯一不同的是从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> 

是否有可能做串用的模板(匹配只是标题部分)匹配?

感谢您的帮助!

+0

您使用XSLT1.0还是XSLT2.0?另外,这个数字是否总是在最后,或者你能得到中间是数字的元素,比如'title1extra'? –

+0

XSLT2.0和数字总是在最后。 – Juicef

+0

@Juicef,现在您已经拥有了一个真正的XSLT 2.0解决方案,即使在最复杂的情​​况下也能正常工作 - 目前被接受的答案无法产生想要的结果。 –

回答

2

对于形titleN,其中N是某个数目,使用一个匹配条件等的元件...

(校正:)

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

一般较少,但快速和肮脏的,如果你想具体标题1通过对TITLE5,你可能也想...

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

几乎完美!对你的第一个解决方案稍作修改,所有的结果都非常好。如果有人绊倒这个问题,修改它的修改是将“名称”更改为“匹配”。 谢谢! – Juicef

+0

是的。名称属性是一个错误。它应该是匹配的。我会相应更新。如果您有XSLT 2.0,Dimitre的match()解决方案会更好。我在发表评论说XSLT 2.0之前写了我的答案,并且假定XSLT 1.0。还要注意,正则表达式在匹配条件下不会出现不情愿的限定符,尽管它在xsl:element name AVT中仍然需要。 –

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的答案呢

+0

啊!所以正则表达式现在完全集成了(没有扩展)?试图找到没有任何具体例子的信息。很高兴知道!谢谢! – Juicef

+0

@Juicef,Yes在XPath 2.0中,这三个函数与RegExes一起使用:'tokenize()','matches()'和'replace()'。除此之外,XSLT 2.0还具有指令'',''和''。这些函数在这里指定:http://www.w3.org/TR/xpath-functions/#string.match并且在这里指定了指令:http://www.w3.org/TR/2007/REC-xslt20 -2007/#正则表达式。每个标准XPath 2.0实现(包括每个兼容的XSLT 2.0处理器)都实现了这些实现。 –

+0

感谢您的链接! – Juicef