Наивный вопрос к знатокам XML/XSLT

sany79

Исходный XML-документ содержит парные элементы, скажем, left и right, и сбалансирован относительно них. Например:
<left/><x/><left/><y/><z/><right/><right/>
Требуется в результате преобразования убрать пары соответствующих друг другу элементов left и right, а то, что находилось между ними, заключить внутрь элемента xxx:
<xxx><x/><xxx><y/><z/></xxx></xxx>
Возможно ли такое выразить на XSL, и если да, то как? Заранее благодарен.

Dasar

> Возможно ли такое выразить на XSL, и если да, то как?
Можно, но тяжело.
Проще будет написать на неком внешнем языке.

sany79

Ух, жаль. Но всё равно спасибо.

6yrop

я думаю не очень и тяжело

sany79

Ну, если кому не лениво будет привести код -- сложный или не очень -- буду очень рад. Но именно на XSL, т. к. привлекать внешние языки не предполагается. Теперь уж вижу, что вопрос мой не такой наивный.

Dasar

Даже без Java-Script-а?
Допустим мы даже нашли правильный <right/> для исходного <left/, а как дальше получить все что находится между <left/> и <right/>?
через following?

sany79

Java Script'а не нужно, потому что задача не для веб-приложений. Документ должен обрабатываться Саксоном или чем-то подобным.

6yrop

да, через following

6yrop

Вот так


<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<root>
<xsl:apply-templates select="*/left[1]"/>
</root>
</xsl:template>
<xsl:template match="left">
<xsl:choose>
<xsl:when test="following::left">
<xxx>
<xsl:copy-of select="following::*[count(following::left) = count(current/following::left)]"/>
<xsl:apply-templates select="following::left[1]"/>
<xsl:apply-templates select="following::right[last- count(current/preceding::left)]"/>
</xxx>
</xsl:when>
<xsl:otherwise>
<xxx>
<xsl:copy-of select="following::*[count(following::right) = count(current/following::right)]"/>
</xxx>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="right">
<xsl:copy-of select="preceding::*[count(preceding::right) = count(current/preceding::right)]"/>
</xsl:template>
</xsl:stylesheet>

6yrop

этот вариант не совсем правильный (я задание не правильно понял но прием с count-ом понятен, да? Если еще нужно и у меня будет время перепешу.

sany79

Большое спасибо, попробую сам разобраться, а уж если останутся вопросы, обращусь.

stm7880783

Меня мучает вопрос:
почему нельзя просто левые теги поменять на соответствующие левые, а правые на правые?
Тогда вроде автоматически будет проделано искомое преобразование, ибо то что между ними -- так и останется между.

6yrop

ты хочешь разбирать XML-файл как строку, как это сделпть на XSLT я не знаю

sany79

Меня посетила такая же мысль, вывести открывающие и закрывающие теги при помощи <xsl:text>&lt;xxx&gt;</xsl:text>, но я не пробовал, можно ли заставить xsl:text заменять "&lt;" на "<". В любом случае такой подход представляется как хулиганский.
Оставить комментарий
Имя или ник:
Комментарий: