2016-10-05 6 views
0

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

У меня есть файл XML с несколькими узлами, такими как:

<Roles> 
    <Role>User</Role> 
    <Purpose>General User</Purpose> 
    <Role>Staff</Role> 
    <Purpose>Company Staff</Purpose> 
    <Role>Admin</Role> 
    <Purpose>Administration</Purpose> 
</Roles> 

мне нужно перебрать эти узлы и печати < Роли > вместе с его соответствием < Цели >. Однако, если я использую для-каждого цикл будет перебирать < Роли > ей хорошо, но печать же < Назначения > для каждого (только первых ролей/Назначения элемента.

Есть ли способ, что я могу синхронизировать их так что, например, когда для-каждый цикл находится на второй итерации он выбирает вторую < Цели > вместе со вторым < роли > так она заканчивается что-то вроде этого?

User - General User 
Staff - Company Staff 
Admin - Administration 

Я был глядя на использование параметров, таких как следующее, но я получаю «element with-param не в этом контексте «ошибка в ошибке» (возможно, отсутствие понимания XSLT с неправильным использованием).

<xsl:param name="i" select="1"/> 

Я должен держать элементы отдельными (то есть я не могу просто сделать < роль > пользователя - Общий пользователь </Role > по причинам раздражающего форматирования, но если кто-то могли подумать альтернативу петли, которая будет работать а я был бы признателен

+0

Какую версию XSLT вы используете? –

+0

Версия 1.0 на данный момент, но может быть в состоянии использовать 2.0. Я создаю файлы .docx, используя PHP, поэтому не уверен, есть ли ограничения в отношении какой версии я могу использовать. Пробовал установить его как версию 2.0 в случае, если решить проблему с помощью xsl: param, но, к сожалению, не удалось. –

+0

"* print наряду с его соответствием *" довольно бессмысленно. Добавьте ожидаемый результат преобразования (как код). –

ответ

0

Использование following-sibling что-то вроде:..

<xsl:for-each select="Role"> 
    <xsl:value-of select="."/> 
    <xsl:text> - </xsl:text> 
    <xsl:value-of select="following-sibling::Purpose[1]"/> 
    <xsl:text>&#xa;</xsl:text> 
</xsl:for-each> 

Работает только в XSLT 1.0 (см. Комментарий Daniel Haley).

+1

Обратите внимание, что если OP действительно переключается на XSLT 2.0, 'next-sibling :: Purpose' будет выводить больше, чем предполагалось (значение каждого следующего назначения для сестры). –

+0

Отлично! Спасибо, следующий брат - это то, что я искал. Не натолкнулся на это из моих предыдущих поисков, но это именно то, что мне было нужно –

1

Вы можете сделать это, используя following-sibling:: axis. Вы должны выбрать первый следующий Purpose sibling.

Там уже ответ, используя xsl:for-each, так вот один с помощью xsl:apply-templates ...

XML Input

<Roles> 
    <Role>User</Role> 
    <Purpose>General User</Purpose> 
    <Role>Staff</Role> 
    <Purpose>Company Staff</Purpose> 
    <Role>Admin</Role> 
    <Purpose>Administration</Purpose> 
</Roles> 

XSLT 1,0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="Roles"> 
    <xsl:copy> 
     <xsl:apply-templates select="Role"/>  
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Role"> 
    <xsl:copy> 
     <xsl:value-of select="concat(., ' - ', following-sibling::Purpose[1])"/>  
    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

Выход (не сюр e, если это результат, который вы хотите, потому что вы не указали, но он показывает концепцию как минимум)

<Roles> 
    <Role>User - General User</Role> 
    <Role>Staff - Company Staff</Role> 
    <Role>Admin - Administration</Role> 
</Roles>