PythonでXML(RSS)を生成する

  • 0
    いいね
  • 0
    コメント

    はじめに

    PythonでRSS ver2を出力する必要があったのですが、その際に何度かコケたのでメモ。

    Pythonはjsonと親和性が高いですが、XMLは扱いづらいように思います。
    以下のようにいくつかライブラリはあるものの何かとやりたいことが実現できず。

    • feedgenerator
      → google製で良さげに見えるが、lastUpdateなど独自仕様のタグを生成できない
    • xml.etree.ElementTree
      → タグ要素に日本語を入れるとExpatErrorが発生

    やり方

    結局DOMオブジェクトからXMLに変換する方法で落ち着いた。

    文字列のXMLテンプレートから生成する場合

    #!/usr/bin/env python
    # coding: utf-8
    
    from xml.dom.minidom import parseString
    
    xml_template = "<rss version=\"2.0\">\
            <channel>\
                <title>title</title>\
                <link>link</link>\
                <description>desctiption</description>\
                <language>ja</language>\
            </channel></rss>"
    dom = parseString(xml_template)
    
    # channelノードを取得
    channel = dom.getElementsByTagName("channel")[0]
    
    # itemノードを生成
    item = dom.createElement('item')
    # channelノードに追加
    channel.appendChild(item)
    
    # サブノードの生成
    subnode = dom.createElement('subnode')
    subnode.appendChild(dom.createTextNode("日本語もOK"))
    # サブノートにattributeとvalueを設定
    subnode_attr = dom.createAttribute('key')
    subnode_attr.value = 'value'
    subnode.setAttributeNode(subnode_attr)
    # itemノードにsubnodeノードを追加
    item.appendChild(subnode)
    
    # domをxmlに変換して整形
    print (dom.toprettyxml())
    
    

    出力

    <?xml version="1.0"?>
    <rss version="2.0">
      <channel>
        <title>title</title>
        <link>link</link>
        <description>desctiption</description>
        <language>ja</language>
        <item>
          <subnode key="value">日本語もOK</subnode>
        </item>
      </channel>
    </rss>
    

    1からXMLを生成する場合

    #!/usr/bin/env python
    # coding: utf-8
    
    import xml.dom.minidom
    
    # DOMオブジェクトの生成
    dom = xml.dom.minidom.Document()
    
    # rootノードの生成と追加
    root = dom.createElement('root')
    dom.appendChild(root)
    
    # サブノードの生成
    subnode = dom.createElement('subnode')
    subnode.appendChild(dom.createTextNode("日本語もOK"))
    # サブノートにattributeとvalueを設定
    subnode_attr = dom.createAttribute('key')
    subnode_attr.value = 'value'
    subnode.setAttributeNode(subnode_attr)
    # itemノードにsubnodeノードを追加
    root.appendChild(subnode)
    
    # domをxmlに変換して整形
    print (dom.toprettyxml())
    

    出力

    <?xml version="1.0"?>
    <root>
      <subnode key="value">日本語もOK</subnode>
    </root>
    

    まとめ

    json最高

    Reference