XMLファイルの扱い
RubyMotion では、ライブラリを読み込めないので rexml を動かすには面倒なことをしないといけないようなので、NSXMLDocument と NSXMLParser を使ってみたメモ。
NSXMLDocument で、XML ファイルを読み込むには、initWithContentsOfURL:options:error: を使う。ここでは、path から NSURL オブジェクトを作って利用している。NSXMLDocumentTidyXML を指定すると、フォーマットがちゃんとしていない XML ファイルをちゃんとした XML に直してから読み込んでくれる。
xmlDoc = NSXMLDocument.alloc.initWithContentsOfURL(NSURL.fileURLWithPath(path),options:NSXMLDocumentTidyXML,error:nil)
このほかにも、initWithXMLString:options:error: で、XML の文字列から作ることできる。たとえば、テキストファイルを読み込んで、なんらかの処理をした上で XML フォーマットにして読み込むとかできる。
読み込んだ NSXMLDocument から、rootElement で、ルート要素の NSXMLElement オブジェクトが取り出せる。
rootElement = xmlDoc.rootElement
NSXMLElement は NSXMLNode を継承しているので、name で要素名が、stringValue で子ノードのテキストが取り出せる。XMLString では、XML タグを保持したままのテキストが得られ、XMLStringWithOptions でオプションを指定して XML テキストが得られる。たとえば、NSXMLNodePrettyPrint をオプションに指定すると、XML として見やすく成形されたテキストとして得られる。
elementName = rootElement.name
text = rootElement.stringValue
ただ、どうやら whitespace のみのノードのテキストは無視されるようなので、うまくいく方法がないかと思ってる。
これら以外に、children で子ノードの配列が、childCount で子ノードの数が、parent で親ノードが得られる。
rootElement.children
rootElement.childCount
rootElement.parent
これで順にノードをたどっていくこともできるが、XPath がわかっていれば、nodesForXPath:error: で直接そのノードにアクセスできる。この場合は、同じ XPath の要素を配列として取り出すことができる。
nodes = rootElement.nodesForXPath(xpath,error:nil)
次に、NSXMLParser を使った場合のメモ。
XML ファイルからは、initWithContentsOfURL で NSXMLParser オブジェクトを作る。NSXMLParser は、setDelegate で delegate を指定して、parse で処理を開始する。
parser = NSXMLParser.alloc.initWithContentsOfURL(NSURL.fileURLWithPath(path))
parser.setDelegate(self)
parser.parse
ここでの処理は delegate のメソッドを用意して、そこで情報を捕まえる。
def parserDidStartDocument(parser)
# ここに、書類ごとにパースを実行した時点の処理を入れる。
end
def parserDidEndDocument(parser)
# ここには、書類ごとにパースの実行を終えた時点の処理を入れる。
end
def parser(parser,didStartElement:elementName,namespaceURI:uri,qualifiedName:name,attributes:attributes)
# ここには、スタートタグが見つかった時の処理を入れる。
# elementName に要素名が入り、attributes には、属性の情報が NSDictionary/Hash で入る。
end
def parser(parser,didEndElement:elementName,namespaceURI:uri,qualifiedName:name)
# ここには、エンドタグが見つかった時の処理を入れる。
# elementName に要素名が入る。
end