この質問は、質問hereの拡張です。ここで提供された @Martin Honnen の回答は、ほぼ正確に私が望むことを行いますが、deep-equal
が呼び出されたときに、以前のテンプレートで削除したかった要素/属性が既に削除されていると誤って予想していました (したがって、シーケンスには存在しません)。に渡されdeep-equal
ます)。
に渡されるシーケンスから要素/属性を削除するにはどうすればよいですか? または、特定の要素/属性を無視するようにdeep-equal
指示するにはどうすればよいですか?deep-equal
XSL:
<!--
When a file is transformed using this stylesheet the output will be
formatted as follows:
1.) Elements named "info" will be removed
2.) Attributes named "file_line_nr" or "file_name" will be removed
3.) Comments will be removed
4.) Processing instructions will be removed
5.) XML declaration will be removed
6.) Extra whitespace will be removed
7.) Empty attributes will be removed
8.) Elements which have no attributes, child elements, or text will be removed
9.) Duplicate sibling elements will be removed
10.) All elements will be sorted by name recursively
11.) All attributes will be sorted by name
-->
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- Set output options -->
<xsl:output indent="yes" method="xml" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<!-- Match any attribute -->
<xsl:template match="@*">
<xsl:copy/>
</xsl:template>
<!-- Match any element -->
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="@*">
<xsl:sort select="local-name()"/>
</xsl:apply-templates>
<xsl:for-each-group select="node() except (processing-instruction(), comment())" group-adjacent="boolean(self::*)">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<xsl:apply-templates select="current-group()">
<xsl:sort select="local-name()"/>
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<!-- Elements/attributes to ignore -->
<xsl:template match="@*[normalize-space()='']|info|@file_line_nr|@file_name|*[not(@*|node())]"/>
<!-- Ignore element nodes which are deep-equal to a preceding sibling element -->
<xsl:template match="*[some $ps in preceding-sibling::* satisfies deep-equal(., $ps)]"/>
</xsl:stylesheet>
XML 入力:
<root>
<!-- foo #1 -->
<foo a="a" file_line_nr="1"/>
<!-- bar #1 -->
<bar>
some text
<info a="a"/>
</bar>
<!-- foo #2 -->
<foo a="a" file_line_nr="2"/><!-- This should be removed because it is identical to the foo #1 except for the "file_line_nr" attribute which should be removed/ignored -->
<!-- baz #1 -->
<baz file_name="some_file.h">
<bam a="a"/>
</baz>
<!-- bar #2 -->
<bar><!-- This should be removed because it is identical to the bar #1 except for the "info" child element which should be removed/ignored -->
some text
<info b="b"/>
</bar>
<!-- baz #2 -->
<baz file_name="some_other_file.h"><!-- This should be removed because it is identical to the baz #1 except for the "file_name" attribute which should be removed/ignored -->
<bam a="a"/>
</baz>
</root>
望ましい出力:
<root>
<foo a="a"/>
<bar>
some text
</bar>
<baz>
<bam a="a"/>
</baz>
</root>