[XML] xmllintを使って、XMLの内容を検証する

2017年6月26日月曜日

bash XML シェルスクリプト

xmllint

前回に引き続き、コマンドからXMLを取り扱う話。
今度はxmllintを使って、XMLの内容を検証してみよう。
今回はXMLの内容検証用にXSDファイルを用意する。

http://xmlsoft.org/xmllint.html

入力データは前回使用した2種類のXMLをそのまま使おう。

フラットな構造のXMLを検証する

planets1.xmlの構造を定義したXSDファイルを用意しよう。
planets要素の下にplanet要素が並ぶ構造を表現する。

planets1.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="planets">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="planet" minOccurs="0" maxOccurs="unbounded">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element name="name" type="xsd:string"/>
              <xsd:element name="diameter" type="xsd:double"/>
              <xsd:element name="mass" type="xsd:double"/>
              <xsd:element name="epoch" type="xsd:date"/>
            </xsd:sequence>
          </xsd:complexType>
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

$ xmllint --noout --schema planets1.xsd planets1.xml
planets1.xml validates

XMLの内容に問題がなければ、上記のように出力される。
試しに planets1.xml の一部を下記のように書き換えると
      <planet>
        <name>水星</name> 
        <diameter>ABC4879.4</diameter> 
        <mass>3.301e+23</mass> 
        <epoch>2008-01-01</epoch> 
      </planet>

$ xmllint --noout --schema planets1.xsd planets1.xml
planets1.xml:5: element diameter: Schemas validity error : Element 'diameter': 'ABC4879.4' is not a valid value of the atomic type 'xs:double'.
planets1.xml fails to validate

diameterの値がdoubleに解釈できない旨のエラーメッセージが表示される。

親要素があるような構造のXMLを検証する

親要素があるような構造のXMLも同様にXSDを作成して、検証してみよう。

planets2.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="list">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="orbits" minOccurs="0" maxOccurs="unbounded">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element name="orbit" type="xsd:string"/>
              <xsd:element name="planets">
                <xsd:complexType>
                  <xsd:sequence>
                    <xsd:element name="planet" minOccurs="0" maxOccurs="unbounded">
                      <xsd:complexType>
                        <xsd:sequence>
                          <xsd:element name="name" type="xsd:string"/>
                          <xsd:element name="diameter" type="xsd:double"/>
                          <xsd:element name="mass" type="xsd:double"/>
                          <xsd:element name="epoch" type="xsd:date"/>
                        </xsd:sequence>
                      </xsd:complexType>
                    </xsd:element>
                  </xsd:sequence>
                </xsd:complexType>
              </xsd:element>
            </xsd:sequence>
          </xsd:complexType>
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

$ xmllint --noout --schema planets2.xsd planets2.xml
planets2.xml validates