У меня есть плоский структурированный XML-файл, как показано ниже:Flat на вложенную структуру на основе значения атрибута с помощью XSLT
<rs>
<r id="r1" lev="0"/>
<r id="r2" lev="1"/>
<r id="r3" lev="0"/>
<r id="r4" lev="1"/>
<r id="r5" lev="2"/>
<r id="r6" lev="3"/>
<r id="r7" lev="0"/>
<r id="r8" lev="1"/>
<r id="r9" lev="2"/>
</rs>
, которые мне нужно преобразовать в гнездовой один. Правило - это что-то, все r[number(@lev) gt 0]
следует вложить в r[number(@lev) eq 0]
. И выход был бы что-то подобное:
<rs>
<r id="r1">
<r id="r2"/>
</r>
<r id="r3">
<r id="r4">
<r id="r5">
<r id="r6"/>
</r>
</r>
</r>
<r id="r7">
<r id="r8">
<r id="r9"/>
</r>
</r>
</rs>
То, что я пытался это следующее преобразование:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="/">
<rs>
<xsl:apply-templates select="node()|@*"/>
</rs>
</xsl:template>
<xsl:template match="r">
<xsl:variable name="lev" select="number(@lev)" as="xs:double"/>
<r>
<xsl:copy-of select="@id"/>
<xsl:apply-templates select="following-sibling::r[not(number(@lev) eq $lev)
and
count(preceding-sibling::r[number(@lev) eq $lev]) eq 1]"/>
</r>
</xsl:template>
</xsl:stylesheet>
Но это не дает мне желаемого результата. Мы высоко оцениваем мою ошибку кодирования или любой другой подход к выполнению работы.
Спасибо, сэр, за то, что он показал мне правильное направление. – Cylian
Michael Kay: Я признаю все, что вы говорите о моих ответах, и несете полную ответственность за это :) –
Я просто хочу, чтобы XSLT 2 был так же широко использован, насколько он был доступен. Ни один из основных браузеров или инфраструктура .NET еще не поддерживает его, без сторонних библиотек. – Flynn1179