xsl:当没有按预期工作时

时间:2012-04-03 21:55:24

标签: xml xslt

我有一个从SQL数据库填充的表。输入的大多数数据都有一个ABN,我可以使用它来查找电子邮件和名称。有些数据没有ABN,只有UID。我不想在表中显示UID,因为98%的时间是不必要的,因此我想使用xsl:when如果没有名称,则将名称字段更改为UID。

以下是XML中2个案例的示例:

    <?xml version="1.0" encoding="UTF-8"?>
    <CourseData>
      <row batchid="0" courseid="10101" createdon="04/03/2012 01:08PM" datecompleted="1:08 PM" datecompletedDateValue="1333483680000" lastupdatebyabn="999999" lastupdatebyuid="tsmith" lastupdateon="04/03/2012 01:08PM" num="2" respondentabn="999999" respondentemail="tsmith@test.com" respondentid="1" respondentname="Thomas Smith" respondentuid="tsmith"/>       
      <row batchid="0" courseid="10101" createdon="04/03/2012 01:08PM" datecompleted="1:08 PM" datecompletedDateValue="1333483697000" lastupdatebyabn="" lastupdatebyuid="jsmith" lastupdateon="04/03/2012 01:08PM" num="3" respondentabn="" respondentemail="" respondentid="2" respondentname=" " respondentuid="jsmith"/>
    </CourseData>

这是我正在使用的XSL,显然无效。

    <xsl:choose>
      <xsl:when test="row[@respondentabn='']">
        <label datafield="@respondentuid"></label>
      </xsl:when>
      <xsl:otherwise>
        <label datafield="@respondentname"></label>
      </xsl:otherwise></xsl:choose></td>

我该如何解决这个问题?

编辑:所以在与我的老板交谈后,他说一个我需要一个循环才能使这个工作正常,但我真的不应该在.xsl中这样做。我修改了我提供数据的sql以便为我做出改变,回想起来,我可能应该首先想到这一点。

2 个答案:

答案 0 :(得分:0)

使用XSLT,您无法检查严格意义上是否存在空字符串。最简单的方法是评估逆:

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

    <xsl:template match="/">
        <doc>   
           <xsl:apply-templates select="CourseData/row"/>   
        </doc>
    </xsl:template>

    <xsl:template match="CourseData/row"> 
        <xsl:choose>
            <xsl:when test="@respondentabn!=''"> 
                <xsl:element name="label">
                    <xsl:attribute name="datafield">
                       <xsl:value-of select="@respondentname"></xsl:value-of>   
                    </xsl:attribute>
                </xsl:element>
            </xsl:when>
            <xsl:otherwise>
                <xsl:element name="label">
                    <xsl:attribute name="datafield">
                        <xsl:value-of select="@respondentuid"></xsl:value-of>
                    </xsl:attribute>
                </xsl:element>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template> 

</xsl:stylesheet>

产生

<doc><label datafield="Thomas Smith" /><label datafield="jsmith" /></doc>

另一种方法是将respondentabn属性的值赋给变量,然后可以针对变量计算when子句:

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

    <xsl:template match="/">
        <doc>   
           <xsl:apply-templates select="CourseData/row"/>   
        </doc>
    </xsl:template>

    <xsl:template match="CourseData/row"> 
        <xsl:variable name="respondentabn">
           <xsl:value-of select="@respondentabn"/>
        </xsl:variable>

        <xsl:choose>
          <xsl:when test="$respondentabn=''">
            <xsl:element name="label">
               <xsl:attribute name="datafield">
                  <xsl:value-of select="@respondentuid"/>
               </xsl:attribute>
            </xsl:element>
          </xsl:when>
          <xsl:otherwise>
            <xsl:element name="label">
               <xsl:attribute name="datafield">
                  <xsl:value-of select="@respondentname"/>
               </xsl:attribute>
            </xsl:element>
          </xsl:otherwise>
        </xsl:choose>

    </xsl:template> 

</xsl:stylesheet>

产生:

<doc><label datafield="Thomas Smith" /><label datafield="jsmith" /></doc>

这两种方法都可以满足您的需求,而这对您来说更容易理解。

答案 1 :(得分:0)

你没有给出样式表的很多指示,所以很难确定,但我猜你有类似的东西

<xsl:for-each select="row">
<xsl:choose>
      <xsl:when test="row[@respondentabn='']">
        <label datafield="@respondentuid"></label>
      </xsl:when>
      <xsl:otherwise>
        <label datafield="@respondentname"></label>
      </xsl:otherwise>
</xsl:choose>
</xsl:for-each>

或者在任何情况下,如果当前节点是行[@ respondentabn ='']做任何有用的事情,它必须是行的父节点,在这种情况下<label datafield="@respondentuid">将选择父节点的属性(即使AVT语法已得到纠正。)

所以我猜:

<xsl:for-each select="row">
<xsl:choose>
      <xsl:when test="string(@respondentabn)">
        <label datafield="{@respondentuid}"></label>
      </xsl:when>
      <xsl:otherwise>
        <label datafield="{@respondentname}"></label>
      </xsl:otherwise>
</xsl:choose>
</xsl:for-each>

或者,更简洁

<xsl:for-each select="row">
   <label datafield="{@respondentuid[string(.)]|
                      @respondentname[not(string(../@respondentuid))]}"/>
 </xsl:for-each>