2010-06-17 84 views
1

我试图使用<xsl:for-each select="@*">来获取给定元素的所有属性,但是当我这样做时,我的<xsl:choose>语句不执行。遍历XSLT中XML元素的所有属性

这里是我的工作元素:
<textBox id="Airfare" value="" label="text 1"/>

下面是我使用的XSLT模板:

<xsl:template match="textBox"> 
<div> 
    <xsl:choose> 
     <xsl:when test="@label"> 
      <xsl:value-of select="@label"/> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:text>No Label Defined</xsl:text> 
     </xsl:otherwise> 
    </xsl:choose> 
<xsl:element name="input"> 
    <xsl:attribute name="type">text</xsl:attribute> 
    <xsl:for-each select="@*"> 
     <xsl:choose> 
      <xsl:when test="@id"> 
       <xsl:attribute name="name">form_<xsl:value-of select="@id"/></xsl:attribute> 
       <xsl:attribute name="id">form_<xsl:value-of select="@id"/></xsl:attribute> 
      </xsl:when> 
      <xsl:when test="@label"> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:copy-of select="current()"/> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:for-each> 
</xsl:element> 
</div> 

当我生成HTML使用PHP我得到这个:

<div>text 1<input type="text" id="Airfare" value="" label="text 1"></div> 

正如您所看到的,它没有将form_添加到id属性中,它没有生成名称属性,也没有跳过标签属性。

+1

好问题(1)。请参阅我的回答以解释问题以及符合XSLT精神的简短而简单的解决方案。 – 2010-06-17 15:39:46

回答

1

嗨,你已经取得2个错误:如果当前的属性是wrong.The正确的(在我当然认为)

  1. 测试:名称()=“ID”
  2. 选择的电流值属性应该使用'。'来选择。

基本上在for-each循环的主体中,您当前的元素是一个属性。这是一个配对名称和价值。所以使用name()会为您提供名称,并且默认情况下会选择该值。

<xsl:template match="textBox"> 
    <div> 
     <xsl:choose> 
     <xsl:when test="@label"> 
      <xsl:value-of select="@label"/> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:text>No Label Defined</xsl:text> 
     </xsl:otherwise> 
     </xsl:choose> 
     <xsl:element name="input"> 
     <xsl:attribute name="type">text</xsl:attribute> 
     <xsl:for-each select="@*"> 
      <xsl:choose> 
      <xsl:when test="name() = 'id'"> 
       <xsl:attribute name="name">form_<xsl:value-of select="."/> 
       </xsl:attribute> 
       <xsl:attribute name="id">form_<xsl:value-of select="."/> 
       </xsl:attribute> 
      </xsl:when> 
      <xsl:when test="@label"> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:copy-of select="current()"/> 
      </xsl:otherwise> 
      </xsl:choose> 
     </xsl:for-each> 
     </xsl:element> 
    </div> 
    </xsl:template> 

我建议你改变其他测试条款的测试条件。

PS这取决于你的XSL转换,但你可能会想删除创建新的HTML的白色空间属性,比如这一个:

 <xsl:attribute name="id"> 
     form_<xsl:value-of select="."/> 
     </xsl:attribute> 

必须是:

<xsl:attribute name="name">form_<xsl:value-of select="."/> 
2
<xsl:element name="input">  
    <xsl:attribute name="type">text</xsl:attribute>  

    <xsl:for-each select="@*">  
     <xsl:choose>  
      <xsl:when test="@id"> 

这测试当前节点(属性)是否具有名为0123的属性。由于属性本身不具有属性,因此测试永远不会成功。

下面是使用模板的简明XSLT溶液,没有<xsl:for-each>和没有条件逻辑

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:my="my:my" exclude-result-prefixes="my"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:variable name="vNoLabelVal" select="'No Label Defined'"/> 

<xsl:template match="textBox"> 
    <xsl:value-of select="concat(@label, substring($vNoLabelVal, 1 div not(@label)))"/> 
    <input type="text"> 
    <xsl:apply-templates select="@*"/> 
    </input> 
</xsl:template> 

<xsl:template match="textBox/@*"> 
    <xsl:copy-of select="."/> 
</xsl:template> 

<xsl:template match="textBox/@id"> 
    <xsl:attribute name="name"> 
    <xsl:value-of select="concat('form_', .)"/> 
    </xsl:attribute> 
</xsl:template> 

<xsl:template match="textBox/@label"/> 
</xsl:stylesheet> 

当该变换是在给定的XML文档施加:

<textBox id="Airfare" value="" label="text 1"/> 

产生所需的正确结果

当此XML文档施加
text 1<input type="text" name="form_Airfare" value="" /> 

(缺少label属性):

<textBox id="Airfare" value="" /> 

正确的结果产生

No Label Defined<input type="text" name="form_Airfare" value="" />