2011-03-02 45 views
1

我有下面的XMLXSLT转换,字符串连接

<R N="14" MIME="application/pdf"> 
    <RK>7</RK> 
    <MT N="Abstract" 
     V="Lorem Ipsum is simply dummy text of the printing " /> 
    <MT N="Abstract1" 
    V="and typesetting industry. Lorem Ipsum has been the industry's standard "/> 
    <MT N="Author" V="Bernard Shaw;" /> 
    <MT N="Author1" V="Mark Twain" /> 
    <MT N="Abstract2" 
    V="dummy text ever since the 1500s, when an unknown printer took a galley"/> 
    <LANG>en</LANG> 
</R> 

当使用XSLT转换,我需要连接的摘要和作者字段,并显示它像

Abstract: Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley 

Author: Bernard Shaw;Mark Twain 

摘要, Abstract1,Abstract2可能以任何顺序出现在xml中。

我想使用类似以下,但卡在条件&串联串的时候摘要,Abstract1不会以相同的顺序

<xsl:template match="MT"> 
    <xsl:if test="(some generic condition to display Title)"> 
     <br/> 
     <span class="f"> 
      <xsl:value-of select="@N"/> 
     </span> 
    </xsl:if> 
    <xsl:value-of select="@V"/> 
</xsl:template> 

得到任何帮助出现。

+0

如果您可以给出示例输出(您看到的以及您想看到的内容),这会很有帮助。 – kojiro 2011-03-02 14:33:57

+0

好问题,+1。看到我的答案是一个完整的,简短的,简单的解决方案,它被重构为最通用的。 :) – 2011-03-02 14:49:06

+0

检查我的答案只是改变规则匹配'MT'元素的分组方法。 – 2011-03-02 15:39:28

回答

2

该转化

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

<xsl:template match="/"> 
    Abstract: <xsl:text/> 
    <xsl:for-each select="*/MT[starts-with(@N, 'Abstract')]"> 
     <xsl:value-of select="@V"/> 
    </xsl:for-each> 
    Author: <xsl:text/> 
    <xsl:for-each select="*/MT[starts-with(@N, 'Author')]"> 
     <xsl:value-of select="@V"/> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

当所提供的XML文档应用:

<R N="14" MIME="application/pdf"> 
    <RK>7</RK> 
    <MT N="Abstract" V="Lorem Ipsum is simply dummy text of the printing " /> 
    <MT N="Abstract1" V="and typesetting industry. Lorem Ipsum has been the industry's standard " /> 
    <MT N="Author" V="Bernard Shaw;" /> 
    <MT N="Author1" V="Mark Twain" /> 
    <MT N="Abstract2" V="dummy text ever since the 1500s, when an unknown printer took a galley" /> 
    <LANG>en</LANG> 
</R> 

产生想要的结果:

Abstract: Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley 
Author: Bernard Shaw;Mark Twain 

此外重构

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

<xsl:template match="/"> 
    Abstract: <xsl:text/> 
    <xsl:call-template name="concatAttributes"/> 
    Author: <xsl:text/> 
    <xsl:call-template name="concatAttributes"> 
     <xsl:with-param name="pKeyStartString" select="'Author'"/> 
    </xsl:call-template> 
</xsl:template> 

<xsl:template name="concatAttributes"> 
    <xsl:param name="pKeyAttribName" select="'N'"/> 
    <xsl:param name="pKeyStartString" select="'Abstract'"/> 
    <xsl:param name="pValueAttribName" select="'V'"/> 

    <xsl:for-each select= 
     "*/MT[starts-with(@*[name()=$pKeyAttribName], $pKeyStartString)]"> 
     <xsl:value-of select="@*[name()=$pValueAttribName]"/> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

第二重构(由OP请求):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text"/> 
    <xsl:strip-space elements="*"/> 
    <xsl:variable name="vAbstract"> 
     <xsl:apply-templates mode="retrieve" select="//MT"/> 
    </xsl:variable> 
    <xsl:variable name="vAuthors"> 
     <xsl:apply-templates mode="retrieve" select="//MT"> 
      <xsl:with-param name="pKeyStartString" select="'Author'"/> 
     </xsl:apply-templates> 
    </xsl:variable> 

    <xsl:template match="/"> 
    Abstract: <xsl:value-of select="$vAbstract"/> 
    Authors:: <xsl:value-of select="$vAuthors"/> 
    </xsl:template> 

    <xsl:template match="MT" mode="retrieve"> 
     <xsl:param name="pKeyAttribName" select="'N'"/> 
     <xsl:param name="pKeyStartString" select="'Abstract'"/> 
     <xsl:param name="pValueAttribName" select="'V'"/> 
     <xsl:if test="starts-with(@*[name()=$pKeyAttribName], $pKeyStartString)"> 
      <xsl:value-of select="@*[name()=$pValueAttribName]"/> 
     </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

EDIT:该OP已请求“的所有处理应于进行模板匹配MT“。虽然在简单情况下可能会发生这种情况(请参阅@ Alejandro的答案),但在匹配MT的单个模板中执行所有处理会打开未知数的巨大差距。例如,可能需要以不同的方式处理其他MT元素,在这种情况下,根本不会完成这样的处理。在更复杂的情况下(例如元素和属性以任何顺序出现,但输出必须排序时 - Abstract1,Abstract2,...,Abstract-N),则必须明确指定排序并且这必须在匹配MT的模板之外。 因此,在一般情况下,仅在模板匹配的模板MT内才能生成所需的输出。

我建议单模板匹配MT是在一个名为模式,它应该在“拉风”中使用 - 调用方显式应用。

+0

谢谢Dimitre。我正在寻找更通用的东西。这意味着,可能会有许多其他标签,如Abstract&Author。所有这些将遵循格式 - 名称,名称1,名称2,名称3 ....需要显示为名称:值(名称+名称1 + .. +名称N) – itsbalur 2011-03-02 14:48:56

+0

@itsbalur:请参阅我的重构。 :) – 2011-03-02 14:50:22

+0

@Dimitre,再次感谢。我还有一个限制。匹配必须是'',因为我正在尝试做的是更大XSLT的一部分。你能指导我需要改变上述代码来处理这个限制吗? – itsbalur 2011-03-02 15:19:27

0
<xsl:for-each select="MT[starts-with(@N, 'Abstract')]"> 
    <xsl:if test="position() = 1"> 
     <xsl:value-of select="@N"/>: 
    </xsl:if> 
    <xsl:value-of select="@V"/> 
</xsl:for-each> 
0

这个样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:key name="kMtByAlphaN" 
      match="MT" 
      use="concat(generate-id(..),'+',translate(@N,'1234567890',''))"/> 
    <xsl:template match="MT[count(.|key('kMtByAlphaN', 
             concat(
              generate-id(..),'+', 
              translate(@N,'1234567890','') 
             ) 
            )[1] 
          ) = 1 
         ]"> 
     <xsl:variable name="vName" 
         select="translate(@N,'1234567890','')"/> 
     <xsl:value-of select="concat($vName,': ')"/> 
     <xsl:apply-templates select="key('kMtByAlphaN', 
              concat(generate-id(..),'+',$vName) 
            )/@V"/> 
     <xsl:text>&#xA;</xsl:text> 
    </xsl:template> 
    <xsl:template match="text()"/> 
</xsl:stylesheet> 

输出:

Abstract: Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley 
Author: Bernard Shaw;Mark Twain 

注意:由@N字母内容和家长生成的ID,因为我希望几个R元素分组。