Перебирая все атрибуты элемента XML в XSLT - PullRequest
1 голос
/ 17 июня 2010

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

Вот элемент, с которым я работаюс:<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, он не генерировал атрибут имени и не пропускал атрибут label.

Ответы [ 2 ]

2 голосов
/ 17 июня 2010
<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="" />
1 голос
/ 17 июня 2010

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

  1. проверка, если текущий атрибут неверен. Правильно (на мой взгляд, конечно): name () = '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="."/>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...