次のような形式のXMLファイルがたくさんあります。
<Element fruit="Apple" animal="cat" />
ファイルから削除したいもの。
XSLTスタイルシートとLinuxコマンドラインユーティリティxsltprocを使用して、これをどのように行うことができますか?
スクリプトのこの時点までに、削除したい要素を含むファイルのリストが既にあるので、単一のファイルをパラメーターとして使用できます。
編集:質問はもともと意図に欠けていました。
私が達成しようとしているのは、要素「Element」全体を削除することです(fruit == "Apple" && animal == "cat")。同じドキュメントには、「Element」という名前の要素が多数ありますが、これらが残ることを望みます。そう
<Element fruit="orange" animal="dog" />
<Element fruit="Apple" animal="cat" />
<Element fruit="pear" animal="wild three eyed mongoose of kentucky" />
になるでしょう:
<Element fruit="orange" animal="dog" />
<Element fruit="pear" animal="wild three eyed mongoose of kentucky" />
最も基本的なXSLT設計パターンの1つを使用して、「 恒等変換 "をオーバーライドすると、次のように記述できます。
<xsl:stylesheet version = "1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"> <xsl:output exclude-xml-declaration = "yes" /> <xsl:template match = "node()| @ *"> <xsl:copy > <xsl:apply-templates select = "node()| @ *" /> </ xsl:copy> </ xsl:template> <xsl:template match = "Element [@ fruit = 'Apple' and @ animal = 'cat']" /> </ xsl:stylesheet>
Do note値「Apple」を持つ属性「fruit」を持つ「Element」という名前の要素に対してのみ、2番目のテンプレートがID(1st)テンプレートをオーバーライドする方法値「cat」を持つ属性「animal」。このテンプレートの本文は空です。つまり、一致した要素は単に無視されます(一致した場合は何も生成されません)。
この変換が次のソースXMLドキュメントに適用される場合:
<doc> ... <Element name = "same"> foo </ Element> ... <Element fruit = "Apple" animal = "cat"/> <Element fruit = "pear" animal = "cat" /> <Element name = "same"> baz </ Element> ... <Element name = 「同じ」> foobar </ Element> ... </ doc>
必要な結果が生成されます。
<doc> ... <Element name = "same"> foo </ Element> ... <Element fruit = "pear" animal = "cat"/> <Element name = "same"> baz </ Element> ... <Element name = "same"> foobar </ Element> ... </ doc>
アイデンティティーテンプレートの使用とオーバーライドのコードスニペットは他にもありますhere。
@ Dimitre Novatchev による答えは確かに正確でエレガントですが、一般化があります(OPはそれについて尋ねませんでした):フィルターする要素に子要素またはテキストもある場合keepしたいですか?
私はこの小さな変化がそのケースをカバーすると信じています:
<?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"
version="2.0">
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!-- drop DropMe elements, keeping child text and elements -->
<xsl:template match="DropMe">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
一致条件は、他の属性などを指定するために複雑になる場合があり、他のものをドロップする場合は、複数のそのようなテンプレートを使用できます。
したがって、この入力:
<?xml version="1.0" encoding="UTF-8"?>
<mydocument>
<p>Here's text to keep</p>
<p><DropMe>Keep this text but not the element</DropMe>; and keep what follows.</p>
<p><DropMe>Also keep this text and <b>this child element</b> too</DropMe>, along with what follows.</p>
</mydocument>
この出力を生成します:
<?xml version="1.0" encoding="UTF-8"?><mydocument>
<p>Here's text to keep</p>
<p>Keep this text but not the element; and keep what follows.</p>
<p>Also keep this text and <b>this child element</b> too, along with what follows.</p>
</mydocument>
XSLT Cookbook の功績。