概要:
ファイルを入力として受け取り、新しい XSLT 変換を出力として生成するメタXSLT 変換を記述します。paths
この新しい XSLT は、root
入力 XML から注釈付きコピー出力 XML に変換されます。
ノート:
- XSLT 1.0、2.0、または 3.0 で動作します。
- XSLT ベースのインタープリターとのマッチングを再実装するのではなく、ネイティブ XSLT に効果的にコンパイルされるため、生成された変換を大量の入力に対して実行する必要がある場合や、繰り返し実行する必要がある場合は特に、非常に効率的です。
- 要素の祖先をコードで手動で再構築する必要があるアプローチよりも堅牢です。
template/@match
パスを属性にマップするため
、 @match
ing の高度な機能を効率的に利用できます。例として、属性値テストを含めました。
- 特に中間メタ XSLT ファイルが機能しない場合は、@DanielHaley と @MartinHonnen によるエレガントな XSLT 2.0 および 3.0 ソリューションを必ず検討してください。XSLT 3.0 の XPath 評価機能を活用することで、@MartinHonnen の回答は、
template/@match
ここよりもさらに堅牢なマッチングを提供できるようです。
XPath と注釈を指定するこの入力 XML は、次のとおりです。
<paths>
<xpath location="/root/a" annotate="1"/>
<xpath location="/root/a/b" annotate="2"/>
<xpath location="/root/c[@x='123']" annotate="3"/>
</paths>
このメタ XSLT 変換への入力時:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/paths">
<xsl:element name="xsl:stylesheet">
<xsl:attribute name="version">1.0</xsl:attribute>
<xsl:element name="xsl:output">
<xsl:attribute name="method">xml</xsl:attribute>
<xsl:attribute name="indent">yes</xsl:attribute>
</xsl:element>
<xsl:call-template name="gen_identity_template"/>
<xsl:apply-templates select="xpath"/>
</xsl:element>
</xsl:template>
<xsl:template name="gen_identity_template">
<xsl:element name="xsl:template">
<xsl:attribute name="match">node()|@*</xsl:attribute>
<xsl:element name="xsl:copy">
<xsl:element name="xsl:apply-templates">
<xsl:attribute name="select">node()|@*</xsl:attribute>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template match="xpath">
<xsl:element name="xsl:template">
<xsl:attribute name="match">
<xsl:value-of select="@location"/>
</xsl:attribute>
<xsl:element name="xsl:comment">
<xsl:value-of select="@annotate"/>
</xsl:element>
<xsl:element name="xsl:text">
<xsl:text disable-output-escaping="yes">&#xa;</xsl:text>
</xsl:element>
<xsl:element name="xsl:copy">
<xsl:element name="xsl:apply-templates">
<xsl:attribute name="select">node()|@*</xsl:attribute>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
次の XSLT 変換が生成されます。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/root/a">
<xsl:comment>1</xsl:comment>
<xsl:text>
</xsl:text>
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/root/a/b">
<xsl:comment>2</xsl:comment>
<xsl:text>
</xsl:text>
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/root/c[@x='123']">
<xsl:comment>3</xsl:comment>
<xsl:text>
</xsl:text>
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
この入力 XML ファイルを指定すると、次のようになります。
<root>
<a>
<b>B</b>
</a>
<c x="123">C</c>
</root>
目的の出力 XML ファイルが生成されます。
<?xml version="1.0" encoding="UTF-8"?>
<root>
<!--1-->
<a>
<!--2-->
<b>B</b>
</a>
<!--3-->
<c x="123">C</c>
</root>