如何使用XSLT..PART-2将此XML转换为HTML?

时间:2011-11-14 10:35:49

标签: html xml xslt

以下是XML代码 -

<groups>
  <group i=1>
    <member t="P.M" c="Y">ABC</member>
    <member t="P.L">PQR</member>
    <member t="M">XYZ</member>
  </group>
  <group i=2>
    <member t="M" c="Y">ABC</member>
    <member t="M">PQR</member>  
  </group>
  <group i=3>
    <member t="P.L" c="Y">ABC</member>
    <member t="M">PQR</member>  
    <member t="M">XYZ</member>  
  </group>
  <group i=4>
    <member t="M">ABC</member>
    <member t="M" c="Y">PQR</member>    
  </group>
  <group i=5>
    <member t="M">ABC</member>
    <member t="M" c="Y">PQR</member>    
    <member t="M" c="Y">XYZ</member>    
  </group>
  <group i=6>
    <member t="M" dec="Y">ABC</member>
  </group>

</groups>

使用 XSLT 1.0 -

的HTML输出
<U>ABC</U>, P.M, PQR, P.L and XYZ, M
<U>ABC</U> and PQR, MM
<U>ABC</U>, P.L, PQR and XYZ, MM
ABC and <U>PQR</U>, MM
ABC, <U>PQR</U> and <U>XYZ</U>, MM
<U>ABC</U>, M

上述输出的部分 XSLT解决方案是 -

<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:output method='html' media-type='text/html'/>
<xsl:template match="/">
  <html>
  <body>
<xsl:apply-templates/>
  </body>
  </html>
</xsl:template>

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

<xsl:template match="member">
   <xsl:choose>
     <xsl:when test='@c = "Y"'>
       <u><xsl:value-of select="."/></u>, <xsl:value-of select='@t'/>
     </xsl:when>
     <xsl:otherwise>
       <b><xsl:value-of select="."/></b>, <xsl:value-of select='@t'/>
     </xsl:otherwise>
   </xsl:choose>
</xsl:template>

<xsl:template match="member[following-sibling::member]">
  <xsl:choose>
    <xsl:when test='@c = "Y"'>
      <u><xsl:value-of select="."/></u>, <xsl:value-of select='@t'/>
      <xsl:text> and </xsl:text>
    </xsl:when>
    <xsl:otherwise>
      <b><xsl:value-of select="."/></b>, <xsl:value-of select='@t'/>
      <xsl:text> and </xsl:text>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="member[following-sibling::member[following-sibling::member]]">
  <xsl:choose>
    <xsl:when test='@c = "Y"'>
      <u><xsl:value-of select="."/></u>, <xsl:value-of select='@t'/>
      <xsl:text>, </xsl:text>
    </xsl:when>
    <xsl:otherwise>
      <b><xsl:value-of select="."/></b>, <xsl:value-of select='@t'/>
      <xsl:text>, </xsl:text>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>
</xsl:stylesheet>

上面的XSLT根据需要以正确的格式提供输出,但是如果<member> 是什么类型,然后如何在最后添加这种类型..?

1 个答案:

答案 0 :(得分:1)

在回答您的直接问题时,要为成员输出正确数量的 t 元素,您可以执行以下操作:

<xsl:apply-templates select="../member/@t[. = current()/@t]"/>

因此,它将为每个匹配的@t属性输出一个值。

但是,我认为你需要阅读更多关于分组的内容,正如迈克尔凯先生在你上一期提出的问题中提出的那样。

在这种情况下,您要按属性和成员属性进行分组。所以,你要定义一个键,就像这样

<xsl:key name="members" match="member" use="concat(../@i, '|', @t)"/>

请注意使用管道 | 来连接密钥的两个部分。您需要选择一个在密钥的任何部分都不会出现的字符。

然后,您可以像这样获得每个组的第一个元素

<xsl:apply-templates 
 select="group/member[generate-id() = generate-id(key('members', concat(../@i, '|', @t))[1])]"
 mode="group"/>

要迭代组中的所有元素,您可以执行此操作...

<xsl:apply-templates select="key('members', concat(../@i, '|', @t))"/>

所以,给定以下XML

<groups>
   <group i="1">
      <member t="P.M" c="Y">ABC</member>
      <member t="P.L">PQR</member>
      <member t="M">XYZ</member>
   </group>
   <group i="2">
      <member t="M" c="Y">ABC</member>
      <member t="M">PQR</member>
   </group>
   <group i="3">
      <member t="P.L" c="Y">ABC</member>
      <member t="M">PQR</member>
      <member t="M">XYZ</member>
   </group>
   <group i="4">
      <member t="M">ABC</member>
      <member t="M" c="Y">PQR</member>
   </group>
   <group i="5">
      <member t="M">ABC</member>
      <member t="M" c="Y">PQR</member>
      <member t="M" c="Y">XYZ</member>
   </group>
   <group i="6">
      <member t="M" c="Y">ABC</member>
   </group>
</groups>

使用以下XSLT ....

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

   <xsl:key name="members" match="member" use="concat(../@i, '|', @t)"/>

   <xsl:template match="/groups">
      <xsl:apply-templates select="group/member[generate-id() = generate-id(key('members', concat(../@i, '|', @t))[1])]" mode="group"/>
   </xsl:template>

   <xsl:template match="member" mode="group">
      <xsl:apply-templates select="key('members', concat(../@i, '|', @t))"/>
      <xsl:text>, </xsl:text>
      <xsl:apply-templates select="../member/@t[. = current()/@t]"/>
      <xsl:variable name="others" select="count(following-sibling::member[@t != current()/@t])" />
      <xsl:choose>
         <xsl:when test="$others &gt; 1">, </xsl:when>
         <xsl:when test="$others = 1"> and </xsl:when>
         <xsl:otherwise>
            <xsl:text>&#13;</xsl:text>
         </xsl:otherwise>
      </xsl:choose>
   </xsl:template>

   <xsl:template match="member">
      <xsl:choose>
         <xsl:when test="@c='Y'">
            <u>
               <xsl:value-of select="."/>
            </u>
         </xsl:when>
         <xsl:otherwise>
            <xsl:value-of select="."/>
         </xsl:otherwise>
      </xsl:choose>
      <xsl:variable name="others" select="count(following-sibling::member[@t = current()/@t])" />
      <xsl:choose>
         <xsl:when test="$others &gt; 1">, </xsl:when>
         <xsl:when test="$others = 1"> and </xsl:when>
      </xsl:choose>
   </xsl:template>
</xsl:stylesheet>

以下是输出....

<u>ABC</u>, P.M, PQR, P.L and XYZ, M
<u>ABC</u> and PQR, MM
<u>ABC</u>, P.L, PQR and XYZ, MM
ABC and <u>PQR</u>, MM
ABC, <u>PQR</u> and <u>XYZ</u>, MMM
<u>ABC</u>, M
相关问题