根据其他节点的值更新节点值

时间:2015-06-06 01:12:31

标签: xml xslt

我正在尝试根据其他节点的值更新一个节点的属性。

我的XML:

Step/NodeArgs[@status='Information']/Disp = PASS

我的输出是HTML。在我的XML中,可能有许多步骤块。对于每个步骤块,只有一个完成和信息步骤。因此,对于每个完成步骤块,“信息”步骤会通知该块是否为“通过/失败”。因此,我想将XML转换为XML,然后转换为HTML,而无需对CDATA进行硬编码。

  • 如果Step/NodeArgs[@status='Done']/Disp,则PASSBAR应为Status = Done

即使我可以将Status = PASSDone更改为<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output encoding="utf-8" method="html" omit-xml-declaration="yes" indent="yes"/> <xsl:template match="/Report/Action"> <html> <head> <style type="text/css"> body { font-family:Tahoma; font-size:9pt; } h2 {color: #b48608; font-style: italic; text-align: center; text-decoration: underline;} table { table-layout: auto; } table, th, td { font-family:Tahoma; font-size:9pt; padding:5px; border-collapse:collapse; vertical-align:top; border:1px solid black; white-space:nowrap; } th, tr.Venue { text-align:left; background-color:#D3D3D3; font-weight: bold; } td.Passed { font-size:11pt; color:Green; text-align:center; } td.Failed { font-size:11pt; color:Red; text-align:center; } tr.Passed { background-color:#AAEEAA; font-weight:bold; } tr.Failed { background-color:#FFAAAA; font-weight:bold; } </style> </head> <body> <table> <th>Venues</th> <th>Status</th> <xsl:variable name="VenueTestStatus" select="Step/NodeArgs[@status='Information']/Disp"/> <xsl:variable name="VenueName" select="Step/NodeArgs[@status='Done']/Disp"/> <xsl:for-each select="$VenueTestStatus"> <xsl:variable name="i" select="position()"/> <tr> <xsl:if test="$VenueTestStatus[$i]='PASS'"> <xsl:attribute name="class">Passed</xsl:attribute> </xsl:if> <xsl:if test="$VenueTestStatus[$i]='FAIL'"> <xsl:attribute name="class">Failed</xsl:attribute> </xsl:if> <td> <a> <xsl:attribute name="href"> <xsl:value-of select="concat('#',$VenueName[$i])" /> </xsl:attribute> <xsl:value-of select="$VenueName[$i]" /> </a> </td> <td> <xsl:value-of select="$VenueTestStatus[$i]" /> </td> </tr> </xsl:for-each> </table> <br/> <hr/> <br/> <table> <xsl:for-each select="Step"> <xsl:if test="NodeArgs/@status != 'Information'"> <tr> <xsl:variable name="IsVenueRow"> <xsl:value-of select="NodeArgs/Disp" disable-output-escaping="no"/> </xsl:variable> <xsl:if test="not(starts-with($IsVenueRow, 'File'))"> <xsl:attribute name="class">Venue</xsl:attribute> </xsl:if> <td> <xsl:variable name="StatusSymbol"> <xsl:value-of select="NodeArgs/@status" disable-output-escaping="no"/> </xsl:variable> <xsl:attribute name="class"> <xsl:value-of select="$StatusSymbol" /> </xsl:attribute> <xsl:choose> <xsl:when test="NodeArgs/@status = 'Passed'"> <xsl:text>&#10004;</xsl:text> </xsl:when> <xsl:when test="NodeArgs/@status = 'Failed'"> <xsl:text>&#10008;</xsl:text> </xsl:when> </xsl:choose> </td> <td> <xsl:choose> <xsl:when test="not(starts-with($IsVenueRow, 'File'))"> <a> <xsl:attribute name="name"> <xsl:value-of select="$IsVenueRow" /> </xsl:attribute> <xsl:value-of select="$IsVenueRow" /> </a> </xsl:when> <xsl:otherwise> <xsl:value-of select="$IsVenueRow" /> </xsl:otherwise> </xsl:choose> </td> </tr> </xsl:if> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet> ,这也很有用。

到目前为止我的XSL

{{1}}

2 个答案:

答案 0 :(得分:1)

一种可能的XSL转换:

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

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

    <xsl:template match="Action[Step/NodeArgs[@status='Information']/Disp = 'PASS']/Step/NodeArgs[@status='Done']/Disp">
        <xsl:copy>
           <xsl:text><![CDATA[PASSBAR]]></xsl:text>
         </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

简要说明:

  1. 身份模板(<xsl:template match="node()|@*">)复制源XML中的每个节点
  2. 另一个模板会覆盖身份模板规则。它选择Step/NodeArgs[@status='Done']/Disp元素,其中对应的Step/NodeArgs[@status='Information']/Disp元素值等于"PASS",并在输出XML中将所选的Disp元素值替换为<![CDATA[PASSBAR]]>

答案 1 :(得分:0)

我认为您需要进行身份转换,然后根据您的条件构建<Disp/>

<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>
  <xsl:template match="node()|@*" >
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="Disp">
    <Disp>
      <xsl:choose>

    <xsl:when test="../../NodeArgs[@status='Information']">
      PASS
    </xsl:when>

    <xsl:when test="../../NodeArgs[@status='Done']">
      PASSBAR
    </xsl:when>

    <xsl:otherwise>
      <!-- Copy this (Disp) tree as is -->
      <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
    </xsl:otherwise>

      </xsl:choose>
    </Disp>
  </xsl:template>
</xsl:stylesheet>

这是身份转换部分:

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

本身,它只会复制源文档。

通过匹配<Disp/>

<xsl:template match="Disp">

我们可以阻止处理器只复制<Disp/>并插入我们自己的版本:

<Disp>
  <xsl:choose>
    <xsl:when test="...">

如果没有任何内容符合我们的<xsl:when/>条件,我们会再次启动身份转换:

<xsl:otherwise>
  <!-- Copy this (Disp) tree as is -->
  <xsl:copy>
    <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
</xsl:otherwise>

继续使用node / attribute-for-node / attribute copy。