要素・属性へのアクセス | XML & DOM

要素へのアクセスの最もシンプルな方法は、ゲッター(__get)により取得することです。
サンプルとして下記のXML文書を使用します。
<?xml version="1.0" encoding="utf-8"?>
<test>
  <foo at="1">
    <bar at="a">aa</bar>
  </foo>
  <foo at="2">
    <bar at="b">bb</bar>
  </foo>
  <foo at="3" a="1" b="2">
    <bar at="c">cc</bar>
    <baz at="d">dd</baz>
  </foo>
</test>
XML文書を読み込むには、load()メソッド を使用してください。戻り値はそのXML文書のルート要素となります。
$doc = Sabel_Xml_Document::create();
$rootElem = $doc->load("XML", "/path/to/test.xml");
echo $rootElem->tagName;  // test
ゲッターを通した場合の戻り値は常に Sabel_Xml_Elements となります。Sabel_Xml_Elements からは、アクセスしたその名前の子要素がいくつあるかを lengthプロパティ で知ることができます。
$doc = Sabel_Xml_Document::create();
$rootElem = $doc->load("XML", "/path/to/test.xml");

$foos = $rootElem->foo;
echo $foos->length;  // 3

$faas = $rootElem->faa;
echo $faas->length;  // 0
Sabel_Xml_Elements からエレメント(Sabel_Xml_Element)を取得するには item()メソッド を使用します。
$doc = Sabel_Xml_Document::create();
$rootElem = $doc->load("XML", "/path/to/test.xml");

$foos = $rootElem->foo;
echo $foos->item(0)->at("at");  // "1"
echo $foos->item(1)->at("at");  // "2"
echo $foos->item(2)->at("at");  // "3"
Sabel_Xml_Elements は配列のように扱うことも可能です。
$doc = Sabel_Xml_Document::create();
$rootElem = $doc->load("XML", "/path/to/test.xml");

$foos = $rootElem->foo;
echo $foos[0]->at("at");  // "1"
echo $foos[1]->at("at");  // "2"
echo $foos[2]->at("at");  // "3"

foreach ($foos as $foo) {
  echo $foo->at("at");  // "1", "2", "3"
}
このXMLの baz要素 にアクセスするには下記のようにします。要素の値(中身)を取得するには、getNodeValue()メソッド を使用します。
※要素の中身がCDATAセクションであったとしても、同様にgetNodeValue()を使用してください。
$doc = Sabel_Xml_Document::create();
$rootElem = $doc->load("XML", "/path/to/test.xml");

$baz = $rootElem->foo[2]->baz[0];

echo $baz->getNodeValue();  // "dd"
なお、Sabel_Xml_Elements の最初の要素のメソッドをコールする際は [0] を省略することもできます。
$rootElem->foo[2]->baz->getNodeValue();
getAttributes()メソッド を使用すると、Sabel_Xml_Attributes が返されます。このオブジェクトは読み取り専用で、値(属性)を変更したり削除することはできません。
$doc = Sabel_Xml_Document::create();
$rootElem = $doc->load("XML", "/path/to/test.xml");
$attrs = $rootElem->foo[2]->getAttributes();

echo $attrs->has("a");   // true
echo $attrs->has("b");   // true
echo $attrs->has("c");   // false

echo $attrs->get("at");  // "3"
echo $attrs->at;         // "3" (__getも可)

var_dump($attrs->toArray());
  //  array(2) {
  //    ["at"]=>
  //    string(1) "3"
  //    ["a"]=>
  //    string(1) "1"
  //    ["b"]=>
  //    string(1) "2"
  //  }

Sabel_Xml_Element

Sabel_Xml_Elementクラス は要素取得のための便利なメソッドをいくつも備えています。
サンプルとして、下記のXML文書を使用します。
<?xml version="1.0" encoding="utf-8"?>
<root>
  <test1>
    <foo/>
    <bar/>
    <baz/>
  </test1>
  <test2/>
  <test3/>
  <test4/>
  <test5/>
</root>
子要素を全て取得するには getChildren()メソッド を使用します。このメソッドの戻り値は Sabel_Xml_Elements となります。
$doc = Sabel_Xml_Document::create();
$rootElem = $doc->load("XML", "/path/to/test.xml");

foreach ($rootElem->getChildren() as $child) {
  echo $child->tagName;  // "test1", "test2", "test3", ...
}
兄弟要素を全て取得するには、getSiblings()メソッド を使用します。このメソッドの戻り値も Sabel_Xml_Elements となります。
$doc = Sabel_Xml_Document::create();
$rootElem = $doc->load("XML", "/path/to/test.xml");

$test3 = $rootElem->test3[0];
echo $test3->tagName;  // "test3"

foreach ($test3->getSiblings() as $element) {
  echo $element->tagName;  // "test1", "test2", "test4", "test5"
}
1つ前(上)の要素、1つ次(下)の要素を取得するには getPreviousSibling(), getNextSibling()メソッド を使用します。
$doc = Sabel_Xml_Document::create();
$rootElem = $doc->load("XML", "/path/to/test.xml");

$test3 = $rootElem->test3[0];

echo $test3->getPreviousSibling()->tagName;  // "test2"
echo $test3->getNextSibling()->tagName;      // "test4"
似たようなものとして getPreviousSiblings() や getNextSiblings() もあります。戻り値は Sabel_Xml_Elements となります。
$doc = Sabel_Xml_Document::create();
$rootElem = $doc->load("XML", "/path/to/test.xml");

$test3 = $rootElem->test3[0];

foreach ($test3->getPreviousSiblings() as $element) {
  echo $element->tagName;  // "test2", "test1"
}

foreach ($test3->getNextSiblings() as $element) {
  echo $element->tagName;  // "test4", "test5"
}
上記で分かる通り getPreviousSiblings() は上へ上へと要素を辿るためXML文書内の要素の並び順とは逆になります。この挙動に問題がある場合は Sabel_Xml_Elements の reverse()メソッド を実行し、要素の並びを逆順にしてください。
foreach ($test3->getPreviousSiblings()->reverse() as $element) {
  echo $element->tagName;  // "test1", "test2"
}
子要素の最初の要素、または最後の要素を取得するには getFirstChild(), getLastChild()メソッド を使用します。
$doc = Sabel_Xml_Document::create();
$rootElem = $doc->load("XML", "/path/to/test.xml");

$test1 = $rootElem->test1[0];
echo $test1->getFirstChild()->tagName;  // "foo"
echo $test1->getLastChild()->tagName;   // "baz"
親要素を取得するには getParent()メソッド を使用してください。このメソッドの引数には要素名を渡すことが可能で、その場合は指定された要素名の親が見つかるまで親要素を辿って行きます。
$doc = Sabel_Xml_Document::create();
$rootElem = $doc->load("XML", "/path/to/test.xml");

$bar = $rootElem->test1->bar[0];
echo $bar->getParent()->tagName;  // "test1"
echo $bar->getParent("root")->tagName;  // "root"

$bar->getParent("test"); // NULL