Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > XML, XSL > Как проверить атрибут следующей записи


Автор: Millisa 19.1.2010, 12:30
Здравствуйте
 у меня есть xml
Код

<data jsxid="jsxroot">
    <record jsxid="12" jsxTitle="active" jsxPId="13" />
    <record jsxid="115" jsxTitle="beginDate" jsxPId="13"/>
    <record jsxid="162" jsxTitle="WebServices" jsxPId="161"/>
</data>

в xsl коде для применения template я использую проверку:
Код

<xsl:if test="following-sibling::record[1]/@jsxPId=current()/@jsxPId" >
    <xsl:apply-templates mode="child" select="following-sibling::record"/>
    </xsl:apply-templates>
</xsl:if>

почему-то при 
following-sibling::record[1]/@jsxPId=13
current()/@jsxPId=161

все равно мы входим в if . Что я делаю неправильно?? Мне в этом месте нужно зайти в этот xsl только если jsxPId следующего record равен текущему,  в чем может быть ошибка, или это можно реализовать как-то по другому?? Помогите пожалуйста!

Автор: diadiavova 19.1.2010, 12:52
Millisa, приведи весь код. Этот кусок у меня работает правильно. 

И пользуйся разметкой

Автор: diadiavova 19.1.2010, 13:12
Код

<?xml version="1.0" encoding="utf-8" ?>
<data jsxid="jsxroot">
    <record jsxid="12" jsxTitle="active" jsxPId="13" />
    <record jsxid="115" jsxTitle="beginDate" jsxPId="13"/>
    <record jsxid="162" jsxTitle="WebServices" jsxPId="161"/>
</data>
Код

<?xml version="1.0" encoding="utf-8"?>
<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="xml" indent="yes"/>

    <xsl:template match="record">
        <xsl:if test="following-sibling::record[1]/@jsxPId=current()/@jsxPId" >
            <v><xsl:value-of select="@jsxid"/>
        </v>
        </xsl:if>
    </xsl:template>
    <xsl:template match="/">
        <result> 
        <xsl:apply-templates/>
        </result>
    </xsl:template>
</xsl:stylesheet>


И всё это даёт такой вот вывод
Код

<?xml version="1.0" encoding="utf-8"?>
<result>
    <v>12</v>
    
    
</result>
Как видишь отобразился только первый элемент.

Автор: Millisa 19.1.2010, 13:42
Теперь я еще меньше понимаю
Вот мой весь xsl
Код

<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:template match="/">
        <data jsxid="jsxroot">
            <xsl:apply-templates mode="parent" select="*/record">
            </xsl:apply-templates>
        </data>
    </xsl:template>
    
    <xsl:template mode="parent" match="record">
        <xsl:if test="not(@jsxPId=preceding-sibling::record/@jsxPId)">
            <xsl:element name="record">
                <xsl:attribute name="jsxid">
                    <xsl:value-of select="@jsxPId"/>
                </xsl:attribute>
                <xsl:attribute name="jsxPId">
                    <xsl:value-of select="0"/>
                </xsl:attribute>
                <xsl:apply-templates mode="child" select="current()"/>
            </xsl:element>
            <xsl:if test="position()!=last()">
            <xsl:apply-templates mode="parent" select="following-sibling::record"/>
            </xsl:if>
        </xsl:if>
        
    </xsl:template>
    <xsl:template mode="child" match="record">
        <xsl:element name="record">
            <xsl:attribute name="jsxid">
                <xsl:value-of select="@jsxid"/>
            </xsl:attribute>
            <xsl:attribute name="jsxPId">
                <xsl:value-of select="@jsxPId"/>
            </xsl:attribute>
        </xsl:element>
        <xsl:if test="following-sibling::record[1]/@jsxPId=current()/@jsxPId" >
            <v><xsl:value-of select="@jsxid"/>
        </v>
        </xsl:if>
        <xsl:if test="following-sibling::record[1]/@jsxPId=current()/@jsxPId" >
            <xsl:apply-templates mode="child" select="following-sibling::record">
            </xsl:apply-templates>
        </xsl:if>
</xsl:template>
</xsl:stylesheet>



и если применить его к xml то на выходе
Код

- <data jsxid="jsxroot">
- <record jsxid="13" jsxPId="0">
  <record jsxid="12" jsxPId="13" /> 
  <v>12</v> 
  <record jsxid="115" jsxPId="13" /> 
  <record jsxid="162" jsxPId="161" /> 
  </record>
- <record jsxid="161" jsxPId="0">
  <record jsxid="162" jsxPId="161" /> 
  </record>
- <record jsxid="161" jsxPId="0">
  <record jsxid="162" jsxPId="161" /> 
  </record>
  </data>


Т.е. получается если внутри if лежит variable, то условие срабатывает правильно. в моем же случае - неправильно (

Мне на выходе нужно получить вот такой - 
         
Код

<data jsxid="jsxroot">
- <record jsxid="13" jsxPId="0">
        <record jsxid="12" jsxPId="13" /> 
        <record jsxid="115" jsxPId="13" /> 
  </record>
- <record jsxid="161" jsxPId="0">
<record jsxid="162" jsxPId="161" /> 
  </record>
  </data>

Автор: diadiavova 19.1.2010, 13:51
Millisa, а исходный документ где? И что нужно получить в результате?

Добавлено через 48 секунд
Да и ещё...вторая строчка стиля что делает?

Автор: Millisa 19.1.2010, 13:57
входной xml такой 
Код

<data jsxid="jsxroot">
    <record jsxid="12" jsxTitle="active" jsxPId="13" />
    <record jsxid="115" jsxTitle="beginDate" jsxPId="13"/>
    <record jsxid="162" jsxTitle="WebServices" jsxPId="161"/>
</data>


выходной должен быть такой
Код

<data jsxid="jsxroot">
- <record jsxid="13" jsxPId="0">
        <record jsxid="12" jsxPId="13" /> 
        <record jsxid="115" jsxPId="13" /> 
  </record>
- <record jsxid="161" jsxPId="0">
<record jsxid="162" jsxPId="161" /> 
  </record>
  </data>

мне нужно проходя по входному xml смотреть если  jsxPId изменился, то создать parent с id=jsxPId и этот рекорд будет его child, а если не изменился, тогда это child того же parent что уже был ранее создан. 
Все рекорды, относящиеся к одому паренту идут подряд, поэтому я иду по xml и проверяю у следующего рекорда jsxPId такой же или он изменился, если изменился выхожу из template child и создаю нового parent, если не изменился, снова вызываю template child

Добавлено @ 14:05
Если сделать так
Код

<xsl:if test="following-sibling::record[1]/@jsxPId=current()/@jsxPId" >
        <v><xsl:value-of select="@jsxPId"/> </v>
        <xsl:apply-templates mode="child" select="following-sibling::record"/>
</xsl:if>


То если судить по выводу <xsl:value-of select="@jsxPId"/> в if он заходит правильно, но почему-то <xsl:apply-templates ....> выполняет не смотря на то что он находится в if

PS. Вторая случайно скопировалась, уже убрала

Автор: diadiavova 19.1.2010, 14:24
Millisa, я понял задачу, сейчас пока не могу этим заниматься, но потом обмозгую. Одно уточнение: в одну группу элементы попадают только в том случае если в исходном документе они идут подряд, или все элементы с одинаковым атрибутом по которому осуществляется группировка должны оказаться в одной группе?

Автор: Millisa 19.1.2010, 15:29
В одну группу попадают только те что идут подряд с одинаковым jsxPId

Автор: diadiavova 19.1.2010, 15:44
Цитата(Millisa @  19.1.2010,  15:29 Найти цитируемый пост)
В одну группу попадают только те что идут подряд с одинаковым jsxPId 

Тогда всё упрощается
Код

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
    <xsl:output method="xml" indent="yes" />
    <xsl:template match="/">
        <data jsxid="jsxroot">
            <xsl:call-template name="parids"/>
        </data>
    </xsl:template>
    <xsl:template name="group">
        <xsl:param name="parid"/>
        <record jsxid="{$parid}" jsxPId="0">
            <xsl:copy-of select="//record[@jsxPId=$parid]"/>
        </record>
    </xsl:template>
    <xsl:template name="parids">
        <xsl:for-each select="*//record">
            <xsl:if test="not(preceding-sibling::record[last()]/@jsxPId = @jsxPId)">
                <xsl:call-template name="group">
                <xsl:with-param name="parid" select="@jsxPId"/>
            </xsl:call-template>
            </xsl:if>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>
Так вроде работает

Автор: JVM 19.1.2010, 15:44
Я правильно понял:
Код

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="data">
    <data jsxid="jsxroot">
        <xsl:apply-templates mode="parent" select="record"/>
    </data>
</xsl:template>
    
<xsl:template mode="parent" match="record">
    <xsl:if test="not(@jsxPId=preceding-sibling::record/@jsxPId)">
        <record jsxid="{@jsxPId}" jsxPId="0">
            <record jsxid="{@jsxPId}" jsxPId="{@jsxPId}"/>
            <xsl:apply-templates mode="child" select="following-sibling::record[@jsxPId = current()/@jsxPId]"/>
        </record>
    </xsl:if>
</xsl:template>

<xsl:template mode="child" match="record">
        <record jsxid="{@jsxid}" jsxPId="{@jsxPId}"/>
</xsl:template>
</xsl:stylesheet>

Автор: Millisa 19.1.2010, 16:13
Спасибо огромное!!!!!!
Вариант  JVM  smile работает идеально! 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)