Created
March 1, 2011 16:10
-
-
Save Flackus/849361 to your computer and use it in GitHub Desktop.
XML Reverser
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> | |
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/> | |
<!-- Паттерн на все элементы --> | |
<xsl:template match="*"> | |
<!-- Реверсим локальную часть имени --> | |
<xsl:variable name="thisName"> | |
<xsl:call-template name="checkNCName"> | |
<xsl:with-param name="string" select="local-name()"/> | |
</xsl:call-template> | |
</xsl:variable> | |
<!-- Пересоздаем элемент с новым именем, прокидываем nsuri --> | |
<xsl:element name="{$thisName}" namespace="{namespace-uri()}"> | |
<!-- Апплаимся на все атрибуты --> | |
<xsl:apply-templates select="@*"/> | |
<!-- Апплаимся на все ноды --> | |
<xsl:apply-templates> | |
<!-- Переворачиваем document order --> | |
<xsl:sort select="position()" data-type="number" order="descending"/> | |
</xsl:apply-templates> | |
</xsl:element> | |
</xsl:template> | |
<!-- Паттерн на все атрибуты --> | |
<xsl:template match="@*"> | |
<!-- Реверсим локальную часть имени --> | |
<xsl:variable name="thisName"> | |
<xsl:call-template name="checkNCName"> | |
<xsl:with-param name="string" select="local-name()"/> | |
</xsl:call-template> | |
</xsl:variable> | |
<!-- Пересоздаем атрибут с новым именем, прокидываем nsuri --> | |
<xsl:attribute name="{$thisName}" namespace="{namespace-uri()}"> | |
<!-- Реверсим значение атрибута --> | |
<xsl:call-template name="string-reverser"/> | |
</xsl:attribute> | |
</xsl:template> | |
<!-- Священные коровы --> | |
<xsl:template match="@xml:*"> | |
<xsl:copy/> | |
</xsl:template> | |
<!-- Паттерн на все текстовые ноды --> | |
<xsl:template match="text()"> | |
<!-- Реверсим строковое значение --> | |
<xsl:call-template name="string-reverser"/> | |
</xsl:template> | |
<!-- Копируем комменты и инструкции обработки --> | |
<xsl:template match="comment() | processing-instruction()"> | |
<xsl:copy/> | |
</xsl:template> | |
<!-- Храним символы, с которых можно начать NCName --> | |
<!-- Cюда можно положить НЕ любой NCNameChar, а "( Letter | «_» )" --> | |
<xsl:variable name="genName" select=" | |
concat( | |
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', | |
'abcdefghijklmnopqrstuvwxyz', | |
'_' | |
) | |
"/> | |
<!-- Проверяем создаваемое имя --> | |
<xsl:template name="checkNCName"> | |
<xsl:param name="string" select="."/> | |
<!-- Отрезаем последний символ строки --> | |
<xsl:variable name="curLastSymbol" select=" | |
substring($string, string-length($string)) | |
"/> | |
<xsl:choose> | |
<!-- Если последний символ это символ не из $genName --> | |
<xsl:when test=" | |
string( | |
translate( | |
$curLastSymbol, $genName, '' | |
) | |
) | |
"> | |
<!-- Рекурсивно запускаем текущий шаблон --> | |
<xsl:call-template name="checkNCName"> | |
<!-- Передаем строку _без_ последнего символа --> | |
<xsl:with-param name="string" select=" | |
substring($string, 0, string-length($string)) | |
"/> | |
</xsl:call-template> | |
</xsl:when> | |
<!-- Если все ок, реверсим локальную часть имени --> | |
<xsl:otherwise> | |
<xsl:call-template name="string-reverser"> | |
<xsl:with-param name="string" select="$string"/> | |
</xsl:call-template> | |
</xsl:otherwise> | |
</xsl:choose> | |
</xsl:template> | |
<!-- Реверсер строки --> | |
<xsl:template name="string-reverser"> | |
<xsl:param name="string" select="."/> | |
<xsl:param name="stringReversed"/> | |
<xsl:choose> | |
<!-- Пока остается оригинальная строка --> | |
<xsl:when test="$string"> | |
<xsl:call-template name="string-reverser"> | |
<!-- Передаем без первого символа --> | |
<xsl:with-param name="string" select="substring($string, 2)"/> | |
<!-- Отрезаем первый символ и кладем в новую строку --> | |
<xsl:with-param name="stringReversed" select=" | |
concat(substring($string, 1, 1), $stringReversed) | |
"/> | |
</xsl:call-template> | |
</xsl:when> | |
<!-- Иначе закончили переворачивать --> | |
<xsl:otherwise> | |
<xsl:value-of select="$stringReversed"/> | |
</xsl:otherwise> | |
</xsl:choose> | |
</xsl:template> | |
</xsl:stylesheet> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment