2010-06-17 2 views
1

Я пытаюсь использовать <xsl:for-each select="@*">, чтобы захватить все атрибуты данного элемента, но когда я это сделаю, мой оператор <xsl:choose> не выполнит.Цитирование всех атрибутов XML-элемента в XSLT

Вот элемент, который я работаю с:
<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. –

ответ

1

Привет вы сделали 2 ошибки:

  1. тестирования, если текущий атрибут wrong.The правильно (на мой взгляд, конечно) является: имя() = «ID»
  2. Выбор значения тока атрибут должен быть выбран с помощью.

В основном в теле каждого цикла ваш текущий элемент является атрибутом. Это имя и значение пары. поэтому с помощью 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"> 

Это проверяет, имеет ли текущий узел (атрибут) атрибут с именем id. Поскольку атрибут не может иметь атрибуты, тест никогда не будет успешным.

Вот краткое решение 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"/> 

получается желаемый, правильный результат:

text 1<input type="text" name="form_Airfare" value="" /> 

при нанесении на этом XML-документе (отсутствует label атрибут):

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

правильный результат получается:

No Label Defined<input type="text" name="form_Airfare" value="" /> 
Смежные вопросы