XSLT:由管道符号分隔的循环列表项的串联

时间:2018-07-20 16:06:00

标签: xml xslt string-concatenation templating

我正在尝试使用XSLT模板构建XML输出XML具有多个Group GroupName =“ PersonalSocialMedia”项目,其中每个项目确实具有多个组项目。

我的输入XML如下:

<FormData>     
     <Group GroupName="PersonalSocialMedia" Array="true">
            <GroupItem>
              <Element Name="itemID">2</Element>
              <Element Name="NomineePersonalSocialMedia">
                <Code>2</Code>
                <Value>Instagram</Value>
              </Element>
              <Element Name="NomineeSocialMediaUserName">Iuname</Element>
            </GroupItem>
            <GroupItem>
              <Element Name="itemID">1</Element>
              <Element Name="NomineePersonalSocialMedia">
                <Code>1</Code>
                <Value>Facebook</Value>
                </Element>
              <Element Name="NomineeSocialMediaUserName">fname</Element>
            </GroupItem>
          </Group>
          <Group GroupName="PersonalSocialMedia" Array="true">
            <GroupItem>
              <Element Name="itemID">3</Element>
              <Element Name="NomineePersonalSocialMedia">
                <Code>3</Code>
                <Value>LinkedIn</Value>
              </Element>
              <Element Name="NomineeSocialMediaUserName">testname1</Element>
            </GroupItem>
            <GroupItem>
              <Element Name="itemID">2</Element>
              <Element Name="NomineePersonalSocialMedia">
                <Code>4</Code>
                <Value>Twitter</Value>
         </Element>
              <Element Name="NomineeSocialMediaUserName">testname2</Element>
        </GroupItem>
        <GroupItem>
            <Element Name="itemID">1</Element>
            <Element Name="NomineePersonalSocialMedia">
                <Code>1</Code>
                <Value>Facebook</Value>
            </Element>
            <Element Name="NomineeSocialMediaUserName">testname3</Element>
        </GroupItem>
    </Group>
</FormData> 

我想构建最终的XML看起来像这样;也就是说,将每个Groupitem下的元素名称“ NomineePersonalSocialMedia”内的所有Value节点组合在一起,并用逗号分隔,然后再次将这些值与根节点Groupname =“ PersonalSocialMedia”下的项目(由管道符号分隔)组合在一起。但是,多级模板如何无法按预期工作

<PersonalSocialMedia>
   Instagram, Facebook | LinkedIn, Twitter, Facebook
</PersonalSocialMedia> 

这是我为实现所需输出而应用的XSLT

<PersonalSocialMedia>
    <xsl:attribute name="Category">Nominee''s preferred personal social media network</xsl:attribute>
        <xsl:call-template name="Append">
            <xsl:with-param name="List" select="Group[@GroupName=''Nominees'']/GroupItem/Element[@Name=''PersonalSocialMedia'']/Value" />
        </xsl:call-template>
    </xsl:if>
    <xsl:for-each select="Group[@GroupName=''Nominees'']/GroupItem/Group[@GroupName=''PersonalSocialMedia'']/GroupItem">
        <xsl:call-template name="SocialMediaAppend">
            <xsl:with-param name="List" select="Element[@Name=''NomineePersonalSocialMedia'']/Value" />
        </xsl:call-template>
    </xsl:for-each>
    <xsl:call-template name="SocialMediaAppend">
        <xsl:with-param name="List" select="Group[@GroupName=''PersonalSocialMedia'']/GroupItem" />
    </xsl:call-template>
</PersonalSocialMedia>

模板:

这是用来构建所需结果集的模板。

<xsl:template name="SocialMediaAppend">
    <xsl:param name="List" />
    <xsl:for-each select="$List">
        <xsl:if test="position()!=last()"> | </xsl:if>
    </xsl:for-each>
</xsl:template>

现在,模板返回错误的结果集。我可以用单个组项目生成预期结果集,但是当有多个结果集时,它返回错误的结果。

1 个答案:

答案 0 :(得分:0)

使用XSLT 1.0版修复代码示例后,您可以应用以下模板(我将未知代码替换为...

<xsl:template match="/FormData">
  <PersonalSocialMedia>
    ...
    <xsl:for-each select="Group[@GroupName='PersonalSocialMedia']">
        <xsl:call-template name="SocialMediaAppend">         <!-- Call with all 'Value's -->
            <xsl:with-param name="List" select="GroupItem/Element[@Name='NomineePersonalSocialMedia']/Value" />
        </xsl:call-template>
        <xsl:if test="position()!=last()"> | </xsl:if>       <!-- Delimiter between 'Group's --> 
    </xsl:for-each>
  </PersonalSocialMedia>
</xsl:template>

<xsl:template name="SocialMediaAppend">
    <xsl:param name="List" />
    <xsl:for-each select="$List">
        <xsl:value-of select="." /> 
        <xsl:if test="position()!=last()">, </xsl:if>        <!-- Delimiter between 'Value's -->
    </xsl:for-each>
</xsl:template>

将这些模板应用于XML可获得以下结果:

<PersonalSocialMedia>Instagram, Facebook | LinkedIn, Twitter, Facebook</PersonalSocialMedia>

您可以通过省略命名模板来简化此过程。因此模板看起来像:

<xsl:template match="/FormData">
  <PersonalSocialMedia>
    <xsl:for-each select="Group[@GroupName='PersonalSocialMedia']">
      <xsl:for-each select="GroupItem/Element[@Name='NomineePersonalSocialMedia']/Value">
        <xsl:value-of select="." />
        <xsl:if test="position()!=last()">, </xsl:if>
      </xsl:for-each>
      <xsl:if test="position()!=last()"> | </xsl:if>
    </xsl:for-each>
  </PersonalSocialMedia>
</xsl:template>

结果保持不变。我无法估计这是否会对您的代码有所改进,因此可以认为这是一个建议。