xsl stylesheet:获取具有相同属性值的父元素的子元素

时间:2015-12-02 18:49:46

标签: html xml xslt

我正在开发一个JavaFX应用程序,我有一个我要转换为html的xml文件。 xml文件包含一些具有相同属性名称但子名称不同的元素。我想根据具有相同属性值的父元素对子元素进行分组。

xml文件如下所示:



<?xml version="1.0" encoding="UTF-8" ?>
<application>
  <workflow name="Model Structure">
    <name>Model Structure</name>
    <source>Model data</source>
    <type>Aleatory</type>
    <condition>independet</condition>
    <distribution>None</distribution>
    <assumptions>onsdn</assumptions>
  </workflow>
  <workflow name="Model Structure">
    <name>Model Structure</name>
    <source>Poor data</source>
    <type>Aleatory</type>
    <condition>independet</condition>
    <distribution>GLC</distribution>
    <assumptions>nsisodsd</assumptions>
  </workflow>
  </application
&#13;
&#13;
&#13;

我希望输出如下:

&#13;
&#13;
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>

<body>

  <h3>Model Structure</h3>
  <ol type="1">
    <li>
      <p>Source: Model data</p>
      <p>Type: Aleatory</p>
      <p>Conditions: Independent</p>
      <p>Distribution: GLV</p>
      <p>Assumptions: sibsdisbdibs</p>
    </li>
    <li>
      <p>Source: Poor data</p>
      <p>Type: Epistemic with probabilities</p>
      <p>Conditions: Independent</p>
      <p>Distribution: GLV</p>
      <p>Assumptions: sibsdisbdibs</p>
    </li>
  </ol>

  <h3>Boundary Conditions</h3>
  <ol type="1">
    <li>
      <p>Source: Parametric conditions</p>
      <p>Type: Aleatory</p>
      <p>Conditions: Independent</p>
      <p>Distribution: None</p>
      <p>Assumptions: blablabla</p>
    </li>
    <li>
      <p>Source: Some boundaries</p>
      <p>Type: Epistemic with probabilities</p>
      <p>Conditions: Independent</p>
      <p>Distribution: GLV</p>
      <p>Assumptions: sibsdisbdibs</p>
    </li>
  </ol>

</body>

</html>
&#13;
&#13;
&#13;

我在xsl样式表中使用a for each语句,但是我找不到一种好方法来检查迭代中下一个元素的值,并避免在html文件中打印它。

&#13;
&#13;
<xsl:value-of select="@*" />
<xsl:for-each select="application/workflow">
  <xsl:variable name="tempname">
    <xsl:value-of select="name" /></xsl:variable>
  <h3> <xsl:value-of select="@name"/> </h3>
  <ol type="1">
    <ul>
      <p>Source:
        <xsl:value-of select="source" />
      </p>
      <p>Type:
        <xsl:value-of select="type" />
      </p>
      <p>Conditions:
        <xsl:value-of select="condition" />
      </p>
      <p>Distribution:
        <xsl:value-of select="distribution" />
      </p>
      <p>Assumptions:
        <xsl:value-of select="assumptions" />
      </p>
    </ul>
  </ol>
</xsl:for-each>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:2)

以下是2个选项。第一个选项适用于1.0和2.0处理器。第二个选项仅适用于2.0处理器。

XSLT 1.0 / 2.0 (示例:http://xsltransform.net/pPzifpw

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"/>
  <xsl:strip-space elements="*"/>

  <!--Group workflows by name attribute.-->
  <xsl:key name="workflows" match="workflow" use="@name"/>

  <xsl:template match="/*">
    <html>
      <body>
        <!--First workflow in the group.-->
        <xsl:for-each select="workflow[generate-id()=generate-id(key('workflows',@name))]">
          <h3><xsl:value-of select="@name"/></h3>
          <ol type="1">
            <!--All of the workflows in the group.-->
            <xsl:apply-templates select="key('workflows',@name)"/>
          </ol>
        </xsl:for-each>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="workflow">
    <li>
      <xsl:apply-templates select="*[not(self::name)]"/>
    </li>
  </xsl:template>

  <xsl:template match="workflow/*">
    <!--Get the first character of the element name and make it uppercase.-->
    <xsl:variable name="ic" 
      select="translate(substring(name(),1,1),
      'abcdefghijklmnopqrstuvwxyz',
      'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
    <p><xsl:value-of select="concat($ic,substring(name(),2),': ',.)"/></p>
  </xsl:template>

</xsl:stylesheet>

XSLT 2.0 (示例:http://xsltransform.net/bnnZWe

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

  <xsl:template match="/*">
    <html>
      <body>
        <!--First workflow in the group.-->
        <xsl:for-each-group select="workflow" group-by="@name">
          <h3><xsl:value-of select="current-grouping-key()"/></h3>
          <ol type="1">
            <!--All of the workflows in the group.-->
            <xsl:apply-templates select="current-group()"/>
          </ol>
        </xsl:for-each-group>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="workflow">
    <li>
      <xsl:apply-templates select="* except name"/>
    </li>
  </xsl:template>

  <xsl:template match="workflow/*">
    <!--Get the first character of the element name and make it uppercase.-->
    <xsl:variable name="name" 
      select="replace(name(),'^.',upper-case(substring(name(),1,1)))"/>
    <p><xsl:value-of select="concat($name,': ',.)"/></p>
  </xsl:template>


</xsl:stylesheet>
相关问题