как скопировать данные переменной одного foreach в другой для каждого в xslt - PullRequest
0 голосов
/ 24 мая 2011

XML

<swift>
 <message>
     <block2 type="input">
        <messageType>102</messageType>
        <receiverAddress>BKTRUS33XBRD</receiverAddress>
        <messagePriority>N</messagePriority>     
     </block2>
     <block3>
     <tag>
     <name>32</name>
     <value>praveen</value>
     </tag>
     <tag>
     <name>42</name>
     <value>pubby</value>
     </tag>
     </block3> 
     <block4>
     <tag>
     <name>77</name>
     <value>pravz</value>
     </tag>
     <tag>
     <name>77</name>
     <value>pubbypravz</value>
     </tag>
     <tag>
     <name>99</name>
     <value>USA</value>
     </tag>
     <tag>
     <name>99</name>
     <value>UK</value>
     </tag>
     <tag>
     <name>76</name>
     <value>shanmu</value>
     </tag>
  </block4>
 </message>
</swift>

XSL

      <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

          <xsl:output method="text" />
           <xsl:param name="count" select="000001"></xsl:param >
            <xsl:template match="/">
             <xsl:for-each select ="swift/message">

             <xsl:variable name="newtype">
        <xsl:choose>
        <xsl:when test="block2[@type = 'input']">

     <xsl:value-of  select=" concat('O', block2/messageType,block2/messagePriority )"/>,<xsl:text/>
            </xsl:when>

            <xsl:when test="block2[@type = 'output']">
     <xsl:value-of  select=" concat('I', block2/messageType,block2/messagePriority )"/>,<xsl:text/>
        </xsl:when>
           </xsl:choose>
            </xsl:variable>

    <xsl:for-each select ="/swift/message/block3/tag[name='32']">
    <xsl:variable name = "first-val" select="value"/>

    <xsl:for-each select ="/swift/message/block4/tag[name='77']">
    <xsl:value-of select="concat($count,',',$first-val, ',',value)"/>

    <xsl:text>
        </xsl:text>
         </xsl:for-each>
       </xsl:for-each>
    </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

Мне нужно скопировать данные, для которых я объявил имя " newtype ", если данные должнывместо этой нижеприведенной строки напечатайте

  <xsl:value-of select="concat($newtype,',',$first-val, ',',value)"/>

, но выше, которое показывало неверно, потому что имя переменной было объявлено вне области видимости, поэтому любые изменения могут заставить меня достичь этого результата, пожалуйста

вышея горячо закодировал это значение 000001, но для каждой записи требовался прирост

Ожидаемый результат

O102N, 000001, правин, правда, США

O102N, 000002, правин, паббиправз, Великобритания

Ответы [ 2 ]

0 голосов
/ 24 мая 2011

XSLT - это функциональный язык - среди прочего это означает, что переменные являются неизменяемыми - после получения значения они не могут быть изменены.

Решение к этой конкретной проблеме:

Изменить :

<xsl:value-of select="concat($count,',',$first-val, ',',value)"/>

На :

<xsl:value-of select="concat(position(),',',$first-val, ',',value)"/>

Когдаисправленное преобразование применяется к предоставленному документу XML, желаемый результат получается .

0 голосов
/ 24 мая 2011

Можете ли вы показать мне ваш входной XML и желаемый выходной XML?

Я немного съеживаюсь, когда вижу foreach в xsl - это язык шаблонов и редко требует foreach ...

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE stylesheet [
    <!ENTITY comma "<xsl:text>,</xsl:text>">
    <!ENTITY cr "<xsl:text>
</xsl:text>">
]>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
    <xsl:output method="text" indent="no" />
    <xsl:template match="/">
        <xsl:apply-templates select="/swift/message/block4/tag [name='77']"/>
    </xsl:template>

    <xsl:template match="message/block4/tag [name='77']">
        <xsl:apply-templates select="../../block2/@type"/>
        <xsl:value-of select="../../block2/messageType"/>
        <xsl:value-of select="../../block2/messagePriority"/>&comma;
        <xsl:number format="000001"/>&comma;
        <xsl:value-of select="../../block3/tag [name='32']/value"/>&comma;
        <xsl:value-of select="value"/>&cr;
    </xsl:template>

    <xsl:template match="@type[.='input']">O</xsl:template>

    <xsl:template match="@type[.='output']">I</xsl:template>

    <xsl:template match="text()"/>

</xsl:stylesheet>

Вам нужна одна строка для каждого имени блока. Поэтому примените шаблон для этого block4 / tag [name = '77 ']

Затем - для каждого из них выберите родительские элементы, которые вам нужны.

xsl: число будет подсчитывать количество выбранных раз.

Элементы ENTITY предназначены для управления пробелами - в противном случае форматирование дерьмо.

Нет необходимости в foreach. Надеюсь, это поможет

...