Как получить доступ к переменной, определенной в соответствии с условием для каждого цикла / If в другом для каждого цикла

#xslt-2.0

#xslt-2.0

Вопрос:

Мне нужно последовательно генерировать выходные данные, и поэтому я хотел знать, как получить доступ к переменной, определенной в соответствии с условием для каждого цикла / If, а затем значением select внутри другого цикла for .

Согласно моему примеру, как получить доступ к partn и date3? Пожалуйста, помогите и предложите. какова концепция для достижения того же..Я также пробовал с-param , но у меня не получилось.

XSLT:

      <?xml version="1.0" encoding="UTF-8"?>

    <xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:func="myfunc" 
 xmlns:xs="http://www.w3.org/2001/XMLSchema" 
   xmlns:fn="http://www.w3.org/2005/xpath-functions" >
<xsl:output method="text" encoding="utf-8" />
<xsl:output omit-xml-declaration="yes" />
<xsl:param name="break" select="'amp;#xA;'" />
      <xsl:template match="ZGS/ID">
    <xsl:for-each select="E1">   
        <xsl:if test="PA = 'CE'">
            <xsl:variable name="partn" select="PAN"/>
        </xsl:if>
    </xsl:for-each>
    <xsl:for-each select="E13">   
        <xsl:if test="ID = 033">
            <xsl:variable name="date3" 
     select="substring(DAT,3,8)"/>
        </xsl:if>
    </xsl:for-each>
    <xsl:for-each select="E1E">
        <xsl:text>823</xsl:text>
        <xsl:text>03</xsl:text>
        <xsl:for-each select="E1ED">
            <xsl:if test="QU = 012 ">
                <xsl:value-of select="BEL"/>  
            </xsl:if>
        </xsl:for-each>
        <xsl:value-of select="$partn"/>
        <xsl:value-of select="$date3"/>
    </xsl:for-each>
</xsl:template>
  

ВВОД:

      <?xml version='1.0' encoding='utf-8'?>
    <ZGS>
  <ID BEGIN="1">
<E1 SEGMENT="1">
    <PA>AG</PA>
    <NAME>ABC</NAME>
    <SP>E</SP>
    <AND>0004</AND>
</E1>
<E1 SEGMENT="1">
    <PA>RE</PA>
    <PAN>IUIOP</PAN>
    <NAME>ABC1</NAME>
    <SP>EQ</SP>
    <AND>0005</AND>
    <EKA3 SEGMENT="1">
     <QU>009</QU>
    </EKA3>
</E1>
<E1 SEGMENT="1">
    <PA>CE</PA>
    <PAN>PODW</PAN>
    <NAME>ABC2</NAME>
    <SP>EP</SP>
    <AND>0006</AND>
</E1>
<E13 SEGMENT="1">
    <ID>001</ID>
    <DAT>20190329</DAT>
</E13>
<E13 SEGMENT="1">
    <ID>002</ID>
    <DAT>20190429</DAT>
</E13>
<E13 SEGMENT="1">
    <IDD>033</IDD>
    <DAT>20190529</DAT>
</E13>
<E1E>
<E1ED>
</E1ED>
<E1ED>
</E1ED>
</E1E>
  

Ответ №1:

В XSLT переменные, однажды объявленные / определенные, не могут быть изменены. И существует только в том цикле, в котором они определены.

Возможно xsl:for-each , здесь цикл вам не понадобится. Вместо этого переменные могут быть определены глобально, чтобы вы могли использовать их там, где хотите в своем xslt.

Вы можете попробовать следующее:

 <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:func="myfunc"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">

<xsl:output method="text" encoding="utf-8" />
<xsl:output omit-xml-declaration="yes" />
<xsl:param name="break" select="'amp;#xA;'" />

<xsl:variable name="partn" select="/ZGS/ID/E1[PA = 'CE']/PAN" />
<xsl:variable name="date3" select="substring(/ZGS/ID/E13[ID = '033']/DAT,3,8)" />

<xsl:template match="ZGS/ID">
    <xsl:for-each select="E1E">
        <xsl:text>823</xsl:text>
        <xsl:text>03</xsl:text>

        <xsl:for-each select="E1ED">
            <xsl:if test="QU = 012 ">
                <xsl:value-of select="BEL" />
            </xsl:if>
        </xsl:for-each>

        <xsl:value-of select="$partn" />
        <xsl:value-of select="$date3" />
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>
  

https://xsltfiddle .liberty-development.net/jyRYYiu

Используя xsl:param , это может быть достигнуто как

 <xsl:param name="partn" select="/ZGS/ID/E1[PA = 'CE']/PAN" />
<xsl:param name="date3" select="substring(/ZGS/ID/E13[ID = '033']/DAT,3,8)" />

<xsl:template match="ZGS/ID">
    <xsl:for-each select="E1E">
        <xsl:text>823</xsl:text>
        <xsl:text>03</xsl:text>

        <xsl:for-each select="E1ED">
            <xsl:if test="QU = 012 ">
                <xsl:value-of select="BEL" />
            </xsl:if>
        </xsl:for-each>

        <xsl:for-each select="$partn">
            <xsl:value-of select="." />
        </xsl:for-each>

        <xsl:value-of select="$date3" />
    </xsl:for-each>
</xsl:template>
  

https://xsltfiddle .liberty-development.net/jyRYYiu/1

Комментарии:

1. Спасибо за ваш вклад. Таким образом, вы имеете в виду, что мы можем заменить for each мы, которые я применял для повторяющихся фрагментов, объявлением переменной указанным способом. Пожалуйста, исправьте мое понимание.

2. @kuhujain: Да. В обновленной ссылке я добавил один дополнительный блок, где E1/PA есть CE , и его PAN значение равно EXTRAPAN . Обратите внимание, что он будет объединять значение повторяющихся фрагментов. Если вам нужно обрабатывать каждое значение, вы можете добавить for-each объявленные глобальные переменные. Спасибо.

3. Да, поэтому вместо записи <xsl:для каждого select=»E1″><xsl:if test=»PA = ‘CE'»><xsl:имя переменной =»partn» select=»PAN»/></xsl:if>каждый> мы можем написать — <xsl:имя переменной =»partn» select=»/ZGS/ID/E1[PA = ‘CE’]/PAN» /> Оба работают одинаково, но в случае переменной мы можем получить доступ к тому, к чему мы хотим в XSLT.Becoz, какна данный момент я написал так много для каждого и не смог получить доступ к переменным за его пределами. Это работает так, как ожидалось.

4. Кроме того, можем ли мы также записать глобальную переменную внутри шаблона?

5. can we write global variable inside template as well ? : Переменная является глобальной, если она объявлена как элемент верхнего уровня, и локальной, если она объявлена в шаблоне. Если вы определяете переменную в шаблоне, ее можно использовать только в рамках этого шаблона. ИЛИ вы можете передать его в качестве параметра в другой шаблон.