Переменные XSLT для каждого цикла

#xml #xslt

#xml #xslt

Вопрос:

XML-файл:

 <generic-cv:generic-cv xmlns:generic-cv="http://www.cihr-irsc.gc.ca/generic-cv/1.0.0" lang="en" dateTimeGenerated="2014-05-30 11:40:50">
<section id="f589cbc028c64fdaa783da01647e5e3c" label="Personal Information">
    <section id="2687e70e5d45487c93a8a02626543f64" label="Identification" recordId="4f7c2ebd789f407b939e05664f6aa7c0">
        <field id="ee8beaea41f049d8bcfadfbfa89ac09e" label="Title">
            <lov id="00000000000000000000000000000318">Mr.</lov>
        </field>

        <field id="98ad36fee26a4d6b8953ea764f4fed04" label="First Name">
            <value type="String">Hara</value>
        </field>

    </section>
    <section id="2687e70e5d45487c93a8a02626543f64" label="Identification" recordId="4f7c2ebd789f407b939e05664f6aa7c0">
        <field id="ee8beaea41f049d8bcfadfbfa89ac09e" label="Title">
            <lov id="00000000000000000000000000000318">Mr.</lov>
        </field>

        <field id="98ad36fee26a4d6b8953ea764f4fed04" label="First Name">
            <value type="String">ali</value>
        </field>

    </section>
</section>
  

и файл xslt, подобный этому

 <xsl:stylesheet version="1.0"


  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" indent="yes"/>
                                    <xsl:variable name="FirstName" select=".//field[@id='98ad36fee26a4d6b8953ea764f4fed04']/value"/>


<xsl:template match="/">
    <html>
        <head>
        <title>Xml Convertor</title>
    </head>
    <body>
        <h2><b> Personal Information</b></h2>
      <ul>
        <xsl:for-each select=".//section[@id='2687e70e5d45487c93a8a02626543f64']" >

            <li>Name: $FirstName></li>


        </xsl:for-each>                    
        </ul> 
    </body>
</html>
  

Вместо использования определенных значений кода для получения нужной информации в файле xml.
Я хотел использовать (глобальные) переменные, чтобы я мог легко изменять значения.
Например, когда я хочу найти и отобразить (в html) первое имя, я ищу код «98ad36fee26a4d6b8953ea764f4fed04». Вместо этого я хочу установить переменную, например FirstName, в это значение и искать значение переменной в файле xml.Однако, когда я устанавливаю первое имя в переменную и помещаю его под a для каждого цикла, оно будет выводить только имя Hara, а не ali. Есть ли способ, которым я могу решить эту проблему, не помещая объявление переменной в для каждого цикла

Ответ №1:

Выражение выбора an xsl:variable вычисляется в любом контексте, в котором найдено объявление переменной. В вашем примере FirstName переменная будет содержать набор value элементов из всех полей первого имени во всем документе (поскольку контекстом для объявления переменной является корневой узел / ), и value-of этот набор узлов определяется как строковое значение первого узла в наборе в порядке документа, а именно «Хара».

Мне кажется, что вы пытаетесь объявить своего рода функцию, а не переменную — что-то, что даст вам значение поля first name для любого контекста, из которого вы его вызываете. В XSLT 1.0 это означает именованный шаблон

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" indent="yes"/>

  <xsl:template name="firstName">
    <xsl:value-of select=".//field[@id='98ad36fee26a4d6b8953ea764f4fed04']/value" />
  </xsl:template>


  <xsl:template match="/">
    <html>
      <head>
        <title>Xml Convertor</title>
      </head>
      <body>
        <h2><b> Personal Information</b></h2>
        <ul>
          <xsl:for-each select=".//section[@id='2687e70e5d45487c93a8a02626543f64']" >
            <li>Name: <xsl:call-template name="firstName"/></li>
          </xsl:for-each>                    
        </ul> 
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>
  

Когда вы вызываете именованный шаблон, контекст не меняется, поэтому .// в firstName шаблоне будет относительно узла для текущей итерации for-each