XMLで遊ぼう with xmlstarlet
XMLStarlet Command Line XML Toolkit: NewsでXMLをいじくって遊ぼう。
インストール
$ sudo port install xmlstarlet
xmlstarletと毎回打つのは面倒なので、xmlにaliasしておく。
// .zshrc,.bashrcなどに alias xml="xmlstarlet"
整形式(well-formed)であるかのチェック
まずは、XMLがwell-formedであるかのチェック。
これは要するに、タグの対応がとれているか、正しくネストされているかどうかなど、XMLとして最低限満たされる条件を満たしているかのチェック。
well-formedなXML。
<?xml version="1.0" encoding="utf-8" ?> <doc> <para>Hello World!!</para> <para>Second Line</para> </doc>
well-formedでないXML。
<?xml version="1.0" encoding="utf-8" ?> <doc> <para>Hello World!! <para>Second Line</para> </doc>
これは、xml val
でチェックすることができる。
$ xml val valid.xml valid.xml - valid $ xml val invalid.xml invalid.xml:5: parser error : Opening and ending tag mismatch: para line 3 and doc </doc> ^ invalid.xml:6: parser error : Premature end of data in tag doc line 2 ^ invalid.xml - invalid
DTDによる妥当性チェック
次は、DTDによる妥当なXML(vaild XML)かどうかのチェック。
これは、XMLになんらかの制限を付け加えて、その制限を満たしているかを調べる。
例えば、XMLのサブセットであるXHTMLはインライン要素の中にブロック要素を含むことはできない。
妥当なXML。
<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE doc [ <!ELEMENT doc (para+)> <!ELEMENT para (#PCDATA)> ]> <doc> <para>Hello World!!</para> <para>Second Line</para> </doc>
妥当でないXML。
<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE doc [ <!ELEMENT doc (para+)> <!ELEMENT para (#PCDATA)> ]> <doc> <para>Hello World!!</para> <para>Second Line</para> <para><para>Invalid</para></para> </doc>
これは、xml val --embed
(埋め込まれたDTDによるチェック)かxml --dtd
(外部DTDによるチェック)を使う。
$ xml val --embed dtd-valid.xml dtd-valid.xml - valid $ xml val --embed dtd-invalid.xml dtd-invalid.xml:9: element para: validity error : / Element para was declared #PCDATA but contains non text nodes <para><para>Invalid</para></para> ^ dtd-invalid.xml - valid
XSLTによる変換
最後は、XSLTによる変換。
<?xml version="1.0" encoding="utf-8" ?> <doc> <para>Hello World!!</para> <para>Second Line</para> </doc>
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" encoding="utf-8" /> <xsl:template match="doc"> <html> <head> <title>Test Page</title> </head> <body> <xsl:apply-templates /> </body> </html> </xsl:template> <xsl:template match="para"> <p><xsl:apply-templates /></p> </xsl:template> </xsl:stylesheet>
これは、xml tr
を使う。
$ xml tr xslt.xsl doc.xml <?xml version="1.0" encoding="utf-8"?> <html><head><title>Test Page</title></head><body> <p>Hello World!!</p> <p>Second Line</p> </body></html>
# あとは、XML-FOXSL-FOフォーマッタだけだ。