Я следую инструкциям на http://www.ibm.com/developerworks/library/x-tipcombxslt/, чтобы объединить мои XML-файлы. Тем не менее, я хотел бы сделать больше задач сразу и не могу найти способ сделать это. В принципе, я хочу отфильтровать ввод слияния (работает уже) и сортировать вывод (нужна помощь).Фильтровать, объединять и сортировать списки узлов XML
source.xml определяет файлы, содержащие узлы (в моем случае стандартные нарушения кодирования), которые необходимо объединить. Однако некоторые из них содержат нарушения большего количества правил, чем я хочу сохранить на выходе, поэтому я указываю <rule>
, чтобы сохранить в пределах <ruleset>
. Когда правила не указаны, все правила должны быть сохранены.
<rulesets>
<ruleset file="ruleset_M1.xml"/>
<ruleset file="ruleset_all2.xml">
<rule>X</rule>
<rule>Y</rule>
</ruleset>
</rulesets>
Так вот я хочу, чтобы все правила из ruleset_M1.xml
и правил X
и Y
от ruleset_all2.xml
.
ruleset_all2.xml выглядит следующим образом:
<violations>
<violation file="Bra.h" line="1" rule="Z"
msg="Function SPARC_Convert is not documented."/>
<violation file="CpuArch.h" line="120" rule="X"
msg="Parameters of member GetBe32 are not documented."/>
<violation file="CpuArch.h" line="87" rule="X"
msg="Parameters of member GetUi32 are not documented."/>
<violation file="heapmgr.h" line="56" rule="Y"
msg="The following parameter of HeapManager() is not documented: fill"/>
</violations>
и ruleset_M1.xml содержит гораздо больше нарушений гораздо больше правил, которые все должны быть сохранены.
Мне удалось выполнить фильтрацию и слияние с использованием следующего XSLT.
<xsl:stylesheet version="2.0">
<xsl:template match="/rulesets">
<violations>
<xsl:apply-templates>
<xsl:sort select="@file"/><!-- help needed -->
</xsl:apply-templates>
</violations>
</xsl:template>
<xsl:template match="ruleset">
<xsl:choose>
<xsl:when test="rule != ''">
<xsl:variable name="current-rules" select="rule"/>
<xsl:copy-of select="document(@file)/violations/violation[@rule = $current-rules]"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="document(@file)/violations/violation"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Теперь я хочу, чтобы отсортировать вывод по имени файла (violation/@file
), но мой <xsl:sort>
не работает. XPath @file
соответствует атрибуту <ruleset>
, а не <violation>
. Я попытался заменить его document(@file)/violations/violation/@file
и несколькими другими вариантами без успеха. Можно ли каким-либо образом выбрать атрибут в выходных узлах второго шаблона вместо текущего источника? Или я должен полностью изменить свой XSL?