打印,如果只重复第二次节点或只有第一个XSLT

打印,如果只重复第二次节点或只有第一个XSLT

问题描述:

我有这个InputXML打印,如果只重复第二次节点或只有第一个XSLT

<Tokens> 
    <Element>ACNT=256265817; Expires=Wed, 15-Jul-2015 18:25:03 GMT; </Element> 
    <Element>SESSIONID=F4ED9CD79D212993DE8479F97F74FD41; Expires=Wed, 15-Jul-2015 18:25:03 GMT; </Element> 
    <Element>USER_ID=186900873; expires=Wed, 20-Jul-2008 06:25:03 GMT; </Element> 
    <Element>CONFIRM=a4d6f57259de6a2d5d78d0f74bddc19b; expires=Wed, 20-Jul-2008 06:25:03 GMT; </Element> 
    <Element>ID=186900873; expires=Wed, 20-Jul-2008 06:25:07 GMT; </Element> 
    <Element>CONFIRM=a4d6f57259de6a2d5d78d0f74bddc19b; expires=Wed, 20-Jul-2008 06:25:07 GMT; </Element> 
    <Element>SESSIONID=F4ED9CD79D212993DE8479F97F74FD41; Expires=Wed, 15-Jul-2015 18:25:03 GMT; </Element> 
</Tokens> 

而且每次一有最新的到期时间将在下来始终。所以盲目地如何打印第二次重复的项目。请注意,当元素再次出现时,过期时间会发生变化。如果不是重复打印的第一个元素本身

输出是

<Tokens> 
    <Element>ACNT=256265817; Expires=Wed, 15-Jul-2015 18:25:03 GMT; </Element> 
    <Element>ID=186900873; expires=Wed, 20-Jul-2008 06:25:07 GMT; </Element> 
    <Element>CONFIRM=a4d6f57259de6a2d5d78d0f74bddc19b; expires=Wed, 20-Jul-2008 06:25:07 GMT; </Element> 
    <Element>SESSIONID=F4ED9CD79D212993DE8479F97F74FD41; Expires=Wed, 15-Jul-2015 18:25:03 GMT; </Element> 
</Tokens> 

如何给仅在通用的方式在第二元素不看元素值直通XSLT 1.0。作为内部可能会有不同的键开始的值(ID/CONFIRM/SESSIONID/ACNT/GTID等)

我试过设置:不同值,但它是字面上匹配整个文本。在这种情况下不会有任何的监守期满时间

设定不同的码样式模板中:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:set="http://exslt.org/sets"> 
<xsl:template match="/"> 
      <Tokens> 
       <xsl:for-each select="set:distinct(/Tokens/Element)"> 
        <Element><xsl:copy-of select="."/></Element> 
       </xsl:for-each> 
      </Tokens> 
</xsl:template> 
</xsl:stylesheet> 
+0

灿你发布了简化的XSL,展示了你如何完全使用'set:distinct-values'? – har07

这是一种可能的方式:

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

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

    <xsl:template match="Tokens/Element"> 
     <xsl:if test="not(following-sibling::Element[substring-before(.,';')=substring-before(current(),';')])"> 
     <xsl:copy> 
      <xsl:apply-templates select="@* | node()"/> 
     </xsl:copy> 
     </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 
  • <xsl:template match="@* | node()">... :身份模板。将此模板应用于的节点和属性复制到输出XML,保持不变。

  • <xsl:template match="Tokens/Element">...:重写Element节点的身份模板,该节点是Tokens的直接子节点。重复的Element节点部分地由第一个;字符之前的内部文本确定 - 使用substring-before()函数。 Element只复制到输出XML 如果它没有相同的substring-before()的下一个同级,换句话说,对于每个不同的substring-before()值,只复制最后一次出现的元素。

对部分值不能使用set:distinct()。使用Muenchian grouping代替(有小的变化来获得各组,而不是第一的最后一个节点):

XSLT 1.0

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

<xsl:key name="elem-by-val" match="Element" use="substring-before(., ';')" /> 

<xsl:template match="/Tokens"> 
    <Tokens> 
     <xsl:copy-of select="Element[count(. | key('elem-by-val', substring-before(., ';'))[last()]) = 1]"/> 
    </Tokens> 
</xsl:template> 

</xsl:stylesheet> 

注意,应用到您的示例输入,结果:

<?xml version="1.0" encoding="UTF-8"?> 
<Tokens> 
    <Element>ACNT=256265817; Expires=Wed, 15-Jul-2015 18:25:03 GMT; </Element> 
    <Element>USER_ID=186900873; expires=Wed, 20-Jul-2008 06:25:03 GMT; </Element> 
    <Element>ID=186900873; expires=Wed, 20-Jul-2008 06:25:07 GMT; </Element> 
    <Element>CONFIRM=a4d6f57259de6a2d5d78d0f74bddc19b; expires=Wed, 20-Jul-2008 06:25:07 GMT; </Element> 
    <Element>SESSIONID=F4ED9CD79D212993DE8479F97F74FD41; Expires=Wed, 15-Jul-2015 18:25:03 GMT; </Element> 
</Tokens> 

与您的不同,因为USER_IDID不一样。如果你想忽略标签只看该值(这是危险的,因为ACNT和USER_ID可能是仅由巧合相同的),你可以使用

substring-before(substring-after(., '='), ';') 

代替:

substring-before(., ';')