Thibault 10 년 전
커밋
d2eb98f118
5개의 변경된 파일1195개의 추가작업 그리고 0개의 파일을 삭제
  1. 129 0
      books.xml
  2. 119 0
      booksFail.xml
  3. 546 0
      phpunit.phar
  4. 122 0
      test.php
  5. 279 0
      xmlStroller.php

+ 129 - 0
books.xml

@@ -0,0 +1,129 @@
+<?xml version="1.0"?>
+<catalog>
+   <book id="bk101">
+      <author>Gambardella, Matthew</author>
+      <title>XML Developer's Guide</title>
+      <genre>Computer</genre>
+      <price currency="USD">44.95</price>
+      <publish_date>2000-10-01</publish_date>
+      <description>An in-depth look at creating applications 
+      with XML.</description>
+   </book>
+   <book id="bk102">
+      <author>Ralls, Kim</author>
+      <title>Midnight Rain</title>
+      <genre>Fantasy</genre>
+      <price currency="USD">5.95</price>
+      <publish_date>2000-12-16</publish_date>
+      <description>A former architect battles corporate zombies, 
+      an evil sorceress, and her own childhood to become queen 
+      of the world.</description>
+   </book>
+   <book id="bk103">
+      <author>Corets, Eva</author>
+      <title>Maeve Ascendant</title>
+      <genre>Fantasy</genre>
+      <price currency="USD">5.95</price>
+      <publish_date>2000-11-17</publish_date>
+      <description>After the collapse of a nanotechnology 
+      society in England, the young survivors lay the 
+      foundation for a new society.</description>
+   </book>
+   <book id="bk104">
+      <author>Corets, Eva</author>
+      <title>Oberon's Legacy</title>
+      <genre>Fantasy</genre>
+      <price currency="USD">5.95</price>
+      <publish_date>2001-03-10</publish_date>
+      <description>In post-apocalypse England, the mysterious 
+      agent known only as Oberon helps to create a new life 
+      for the inhabitants of London. Sequel to Maeve 
+      Ascendant.</description>
+   </book>
+   <book id="bk105">
+      <author>Corets, Eva</author>
+      <title>The Sundered Grail</title>
+      <genre>Fantasy</genre>
+      <price currency="USD">5.95</price>
+      <publish_date>2001-09-10</publish_date>
+      <description>The two daughters of Maeve, half-sisters, 
+      battle one another for control of England. Sequel to 
+      Oberon's Legacy.</description>
+   </book>
+   <book id="bk106">
+      <author>Randall, Cynthia</author>
+      <title>Lover Birds</title>
+      <genre>Romance</genre>
+      <price currency="USD">4.95</price>
+      <publish_date>2000-09-02</publish_date>
+      <description>When Carla meets Paul at an ornithology 
+      conference, tempers fly as feathers get ruffled.</description>
+   </book>
+   <book id="bk107">
+      <author>Thurman, Paula</author>
+      <title>Splish Splash</title>
+      <genre>Romance</genre>
+      <price currency="USD">4.95</price>
+      <publish_date>2000-11-02</publish_date>
+      <description>A deep sea diver finds true love twenty 
+      thousand leagues beneath the sea.</description>
+   </book>
+   <book id="bk108">
+      <author>Knorr, Stefan</author>
+      <title>Creepy Crawlies</title>
+      <genre>Horror</genre>
+      <price currency="USD">4.95</price>
+      <publish_date>2000-12-06</publish_date>
+      <description>An anthology of horror stories about roaches,
+      centipedes, scorpions  and other insects.</description>
+   </book>
+   <book id="bk109">
+      <author>Kress, Peter</author>
+      <title>Paradox Lost</title>
+      <genre>Science Fiction</genre>
+      <price currency="USD">6.95</price>
+      <publish_date>2000-11-02</publish_date>
+      <description>After an inadvertant trip through a Heisenberg
+      Uncertainty Device, James Salway discovers the problems 
+      of being quantum.</description>
+   </book>
+   <book id="bk110">
+      <author>O'Brien, Tim</author>
+      <title>Microsoft .NET: The Programming Bible</title>
+      <genre>Computer</genre>
+      <price currency="USD">36.95</price>
+      <publish_date>2000-12-09</publish_date>
+      <description>Microsoft's .NET initiative is explored in 
+      detail in this deep programmer's reference.</description>
+   </book>
+   <book id="bk111">
+      <author>O'Brien, Tim</author>
+      <title>MSXML3: A Comprehensive Guide</title>
+      <genre>Computer</genre>
+      <price currency="USD">36.95</price>
+      <publish_date>2000-12-01</publish_date>
+      <description>The Microsoft MSXML3 parser is covered in 
+      detail, with attention to XML DOM interfaces, XSLT processing, 
+      SAX and more.</description>
+   </book>
+   <book id="bk112">
+      <author>Galos, Mike</author>
+      <title>Visual Studio 7: A Comprehensive Guide</title>
+      <genre>Computer</genre>
+      <price currency="USD">49.95</price>
+      <publish_date>2001-04-16</publish_date>
+      <description>Microsoft Visual Studio 7 is explored in depth,
+      looking at how Visual Basic, Visual C++, C#, and ASP+ are 
+      integrated into a comprehensive development 
+      environment.</description>
+   </book>
+   <book>
+      <author>Isundil</author>
+      <title>The id-less book</title>
+      <genre>Computer</genre>
+      <price currency="USD">49.90</price>
+      <price currency="EURO">39.95</price>
+      <publish_date>2015-08-11</publish_date>
+      <description>I have no id what this book is.</description>
+   </book>
+</catalog>

+ 119 - 0
booksFail.xml

@@ -0,0 +1,119 @@
+<?xml version="1.0"?>
+<catalog>
+   <book id="bk101">
+      <author>Gambardella, Matthew</author>
+      <title>XML Developer's Guide</title>
+      <genre>Computer</genre>
+      <price>44.95</price>
+      <publish_date>2000-10-01</publish_date>
+      <description>An in-depth look at creating applications 
+      with XML.</description>
+   </book>
+   <book id="bk102">
+      <author>Ralls, Kim</author>
+      <title>Midnight Rain</title>
+      <genre>Fantasy</genre>
+      <price>5.95</price>
+      <publish_date>2000-12-16</publish_date>
+      <description>A former architect battles corporate zombies, 
+      an evil sorceress, and her own childhood to become queen 
+      of the world.</description>
+   </book>
+   <book id="bk103">
+      <author>Corets, Eva</author>
+      <title>Maeve Ascendant</title>
+      <genre>Fantasy</genre>
+      <price>5.95</price>
+      <publish_date>2000-11-17</publish_date>
+      <description>After the collapse of a nanotechnology 
+      society in England, the young survivors lay the 
+      foundation for a new society.</description>
+   </book>
+   <book id="bk104">
+      <author>Corets, Eva</author>
+      <title>Oberon's Legacy</title>
+      <genre>Fantasy</genre>
+      <price>5.95</price>
+      <publish_date>2001-03-10</publish_date>
+      <description>In post-apocalypse England, the mysterious 
+      agent known only as Oberon helps to create a new life 
+      for the inhabitants of London. Sequel to Maeve 
+      Ascendant.</description>
+   </book>
+   <book id="bk105">
+      <author>Corets, Eva</author>
+      <title>The Sundered Grail</title>
+      <genre>Fantasy</genre>
+      <price>5.95</price>
+      <publish_date>2001-09-10</publish_date>
+      <description>The two daughters of Maeve, half-sisters, 
+      battle one another for control of England. Sequel to 
+      Oberon's Legacy.</description>
+   </book>
+   <book id="bk106">
+      <author>Randall, Cynthia</author>
+      <title>Lover Birds</title>
+      <genre>Romance</genre>
+      <price>4.95</price>
+      <publish_date>2000-09-02</publish_date>
+      <description>When Carla meets Paul at an ornithology 
+      conference, tempers fly as feathers get ruffled.</description>
+   </book>
+   <book id="bk107">
+      <author>Thurman, Paula</author>
+      <title>Splish Splash</title>
+      <genre>Romance</genre>
+      <price>4.95</price>
+      <publish_date>2000-11-02</publish_date>
+      <description>A deep sea diver finds true love twenty 
+      thousand leagues beneath the sea.</description>
+   </book>
+   <book id="bk108">
+      <author>Knorr, Stefan</author>
+      <title>Creepy Crawlies</title>
+      <genre>Horror</genre>
+      <price>4.95</price>
+      <publish_date>2000-12-06</publish_date>
+      <description>An anthology of horror stories about roaches,
+      centipedes, scorpions  and other insects.</description>
+   </book>
+   <book id="bk109">
+      <author>Kress, Peter</author>
+      <title>Paradox Lost</title>
+      <genre>Science Fiction</genre>
+      <price>6.95</price>
+      <publish_date>2000-11-02</publish_date>
+      <description>After an inadvertant trip through a Heisenberg
+      Uncertainty Device, James Salway discovers the problems 
+      of being quantum.</description>
+   </book>
+   <book id="bk110">
+      <author>O'Brien, Tim</author>
+      <title>Microsoft .NET: The Programming Bible</title>
+      <genre>Computer</genre>
+      <price>36.95</price>
+      <publish_date>2000-12-09</publish_date>
+      <description>Microsoft's .NET initiative is explored in 
+      detail in this deep programmer's reference.</description>
+   </book>
+   <book id="bk111">
+      <author>O'Brien, Tim</author>
+      <title>MSXML3: A Comprehensive Guide</title>
+      <genre>Computer</genre>
+      <price>36.95</price>
+      <publish_date>2000-12-01</publish_date>
+      <description>The Microsoft MSXML3 parser is covered in 
+      detail, with attention to XML DOM interfaces, XSLT processing, 
+      SAX and more.</description>
+   </book>
+   <book id="bk112">
+      <author>Galos, Mike</author>
+      <title>Visual Studio 7: A Comprehensive Guide</title>
+      <genre>Computer</genre>
+      <price>49.95</price>
+      <publish_date>2001-04-16</publish_date>
+      <description>Microsoft Visual Studio 7 is explored in depth,
+      looking at how Visual Basic, Visual C++, C#, and ASP+ are 
+      integrated into a comprehensive development 
+      environment.</description>
+</catalog>

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 546 - 0
phpunit.phar


+ 122 - 0
test.php

@@ -0,0 +1,122 @@
+<?php
+
+require_once(__DIR__.'/xmlStroller.php');
+
+class XmlStrollerTester extends PHPUnit_Framework_TestCase
+{
+	public function testLoad()
+	{
+		$parser = new XmlStroller(utf8_encode(file_get_contents(__DIR__."/books.xml")));
+		$success = true;
+		try {
+			$parser = new XmlStroller(utf8_encode(file_get_contents(__DIR__."/booksFail.xml")));
+			$success = false;
+		}
+		catch (Exception $e) {}
+		$this->assertTrue($success);
+	}
+
+	public function testSelectSimpleChild()
+	{
+		$parser = new XmlStroller(utf8_encode(file_get_contents(__DIR__."/books.xml")));
+		$this->assertCount(1, $parser->catalog);
+		$this->assertCount(13, $parser->{"catalog book"});
+		$this->assertCount(13, $parser->{"catalog    book"});
+		$this->assertCount(13, $parser->{"book"});
+		$this->assertContainsOnlyInstancesOf("XmlStroller", $parser->{"catalog book"});
+		$this->assertContainsOnlyInstancesOf("XmlStroller", $parser->{"catalog   book"});
+		$this->assertContainsOnlyInstancesOf("XmlStroller", $parser->{"book"});
+		$this->assertCount(0, $parser->{"fail"});
+		$this->assertCount(0, $parser->{"catalog fail"});
+		$this->assertCount(0, $parser->{"book fail"});
+	}
+
+	public function testSelectDirectChild()
+	{
+		$parser = new XmlStroller(utf8_encode(file_get_contents(__DIR__."/books.xml")));
+		$this->assertCount(1, $parser->{">catalog"});
+		$this->assertCount(1, $parser->{"> catalog"});
+		$this->assertCount(1, $parser->{" > catalog"});
+		$this->assertCount(13, $parser->{"catalog>book"});
+		$this->assertCount(13, $parser->{"catalog >book"});
+		$this->assertCount(13, $parser->{"catalog>  book"});
+		$this->assertCount(13, $parser->{"catalog  >book"});
+		$this->assertCount(13, $parser->{"catalog> book"});
+		$this->assertCount(13, $parser->{"catalog > book"});
+		$this->assertCount(13, $parser->{"catalog   >   book"});
+		$this->assertCount(13, $parser->{" > catalog > book"});
+		$this->assertContainsOnlyInstancesOf("XmlStroller", $parser->{">catalog>book"});
+		$this->assertContainsOnlyInstancesOf("XmlStroller", $parser->{"catalog>book"});
+		$this->assertContainsOnlyInstancesOf("XmlStroller", $parser->{"catalog >book"});
+		$this->assertContainsOnlyInstancesOf("XmlStroller", $parser->{"catalog> book"});
+		$this->assertContainsOnlyInstancesOf("XmlStroller", $parser->{"catalog > book"});
+		$this->assertContainsOnlyInstancesOf("XmlStroller", $parser->{"catalog   >   book"});
+		$this->assertCount(0, $parser->{"catalog > fail"});
+		$this->assertCount(0, $parser->{">fail"});
+	}
+
+	public function testSelectAttribute()
+	{
+		$parser = new XmlStroller(utf8_encode(file_get_contents(__DIR__."/books.xml")));
+		$book = $parser->{"catalog book[id=bk101]"};
+		$this->assertCount(1, $book);
+		$this->assertEquals("bk101", $book[0]->attr("id"));
+		$book = $parser->{"catalog [id=bk101]book"};
+		$this->assertCount(1, $book);
+		$this->assertEquals("bk101", $book[0]->attr("id"));
+		$book = $parser->{"catalog [id=bk101]"};
+		$this->assertCount(1, $book);
+		$this->assertEquals("bk101", $book[0]->attr("id"));
+		$this->assertCount(0, $book = $parser->{"catalog[id=oupas]"});
+		$this->assertCount(12, $parser->{"catalog [id]"});
+		$this->assertCount(12, $parser->{"catalog [id]book"});
+		$this->assertCount(12, $parser->{"catalog book[id]"});
+		$this->assertCount(12, $parser->{"catalog book[id] *[currency]"});
+		$this->assertCount(12, $parser->{"catalog book[id] [currency]"});
+		$this->assertCount(12, $parser->{"catalog book[id] price[currency]"});
+		$this->assertCount(13, $parser->{"catalog book price[currency=USD]"});
+		$this->assertCount(1, $parser->{"catalog book price[currency=EURO]"});
+		$books = $parser->{"price[currency=USD]"};
+		$this->assertEquals(49.90, $books[count($books) -1]->valueDouble());
+		$this->assertEquals(39.95, $parser->{"catalog book price[currency=EURO]"}[0]->valueDouble());
+		$book = $parser->{"book price[currency=EURO]"}[0];
+		$book = $book->parent();
+		var_dump($book);
+		try {
+			$parser->{"catalog book[id=]"};
+			$this->fail("Expected Exception");
+		} catch (\Exception $e) {}
+	}
+
+	public function testGetAttributes()
+	{
+		$parser = new XmlStroller(utf8_encode(file_get_contents(__DIR__."/books.xml")));
+		$this->assertCount(13, $parser->{"catalog >book"});
+		$firstBook = $parser->{"catalog >book"}[0];
+		$this->assertInternalType('string', $firstBook->attr("id"));
+		$this->assertEquals("bk101", $firstBook->attr("id"));
+		$this->assertInternalType('array', $firstBook->attr());
+		$this->assertCount(1, $firstBook->attr());
+		$this->assertNull($firstBook->attr("fail"));
+		$this->assertNull($firstBook->attr("fail", null));
+		$parser->debug = true;
+		$this->assertEquals("test", $firstBook->attr("fail", "test"));
+		$parser->debug = false;
+	}
+
+	public function testFnc()
+	{
+	}
+
+	public function testAttributeFnc()
+	{
+		$parser = new XmlStroller(utf8_encode(file_get_contents(__DIR__."/books.xml")));
+		/*
+		$this->assertCount(1, $parser->{"catalog book[id=bk101]:first-child"});
+		$this->assertCount(1, $parser->{"catalog book:first-child[id=bk101]"});
+		$this->assertCount(1, $parser->{"catalog :first-child[id=bk101]"});
+		$this->assertCount(1, $parser->{"catalog [id=bk101]:first-child"});
+		*/
+	}
+}
+

+ 279 - 0
xmlStroller.php

@@ -0,0 +1,279 @@
+<?php
+
+class XmlNode extends SimpleXmlIterator
+{
+	public function parent()
+	{ return $this->xpath(".."); }
+}
+
+class XmlStroller
+{
+    private $xmlNode;
+    private $fncList = array(
+        "empty" => false,
+        "first-child" => false,
+        "first-of-type" => false,
+        "last-child" => false,
+        "last-of-type" => false,
+        "not" => true,
+        "nth-child" => true,
+        "nth-last-child" => true,
+        "nth-last-of-type" => true,
+        "nth-of-type" => true,
+        "only-of-type" => false,
+        "only-child" => false,
+        "root" => false
+    );
+
+	public $debug = false;
+
+    /**
+     * Create new Stroller for xml $data
+     * @param $data mixed xml data to parse
+	 * if $data is a string, implement SimpleXmlIterator to evaluate it
+	 * if $data is a SimpleXmlIterator
+    **/
+    public function __construct($data)
+    {
+		if (is_string($data))
+			$this->xmlNode = new \XmlNode($data);
+		else if ($data instanceof \XmlNode)
+			$this->xmlNode = $data;
+    }
+
+    private function getTokens($str)
+    {
+        $tokens = preg_split("/([^A-Za-z0-9\*\-\.:])+/", $str, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE);
+        $tokens_final = array();
+        $nbTokens = count($tokens);
+        for ($i = 0; $i < $nbTokens; $i++)
+        {
+			$tokens_final[] = $tokens[$i][0];
+            if ($i < $nbTokens -1)
+            {
+                $tokenOffsetRight = strlen($tokens[$i][0]) + $tokens[$i][1];
+                if ($tokenOffsetRight < $tokens[$i +1][1])
+                {
+                    $token = substr($str, $tokenOffsetRight, $tokens[$i +1][1] - $tokenOffsetRight);
+					$t = trim($token);
+					if (ltrim($token) != $token)
+						$tokens_final[] = " ";
+                    if (!empty($t))
+						$tokens_final[] = $t;
+					if (rtrim($token) != $token)
+						$tokens_final[] = " ";
+                }
+            }
+        }
+        $tokens_final[] = ',';
+        return $tokens_final;
+    }
+
+    private function compile($str)
+    {
+        $tokens = $this->getTokens($str);
+        $result = array();
+        $currentBranch = array();
+        $nbTokens = count($tokens);
+        $childTokenDictionnary = array(">", "+", "~", " ");
+		$inAttribute = false;
+		$attrs = array();
+        $inToken = false;
+		$inParam = false;
+
+        for ($i=0; $i < $nbTokens; $i++)
+        {
+            if ($tokens[$i] == ',')
+            {
+				if (!empty($attrs))
+					$currentBranch[] = array('', array( "value" => "", "fnc" => array(), "attr" => $attrs ));
+				$attrs = false;
+                $result[] = $currentBranch;
+                $currentBranch = array();
+            }
+			else if ($tokens[$i] == '[' && $inAttribute)
+			{
+				$expected = ']';
+				if (!$inAttribute["key"])
+					$expected = 'key';
+				else if (!$inAttribute["sep"])
+					$expected = 'separator or \']\'';
+				else if (!$inAttribute["value"])
+					$expected = 'value';
+				throw new \Exception("Unexpected token '[', expected {$expected}");
+			}
+			else if ($tokens[$i] == '[' && !$inAttribute)
+			{
+				$params = explode(':', $tokens[$i]);
+				$inAttribute = array( "key" => null, "sep" => false, "value" => null );
+			}
+			else if ($inAttribute)
+			{
+				if ($tokens[$i] == ']')
+				{
+					if (!$inAttribute["key"])
+						throw new \Exception("Unexpected token ']', expected name");
+					if ($inAttribute["sep"] !== false && $inAttribute["value"] === null)
+						throw new \Exception("Unexpected token ']', expected value");
+					if ($inToken !== false)
+						$attrs[] = $inAttribute;
+					else
+						$currentBranch[count($currentBranch) -1][1]["attr"][] = $inAttribute;
+					$inAttribute = false;
+				}
+				else
+				{
+					if (!$inAttribute["key"])
+						$inAttribute["key"] = $tokens[$i];
+					else if (!$inAttribute["sep"])
+						$inAttribute["sep"] = $tokens[$i];
+					else if (!$inAttribute["value"])
+						$inAttribute["value"] = $tokens[$i];
+				}
+			}
+            else if (in_array($tokens[$i], $childTokenDictionnary) || empty(trim($tokens[$i])))
+            {
+                if ($inToken && !empty(trim($tokens[$i])))
+                    throw new \Exception("Unexpected token '{$tokens[$i]}', expected name");
+                elseif ($inToken)
+                    continue;
+                $inToken = empty(trim($tokens[$i])) ? '' : $tokens[$i];
+            }
+            else
+            {
+				$params = explode(':', $tokens[$i]);
+                $currentBranch[] = array($inToken === false ? '' : $inToken, array("value" => $params[0], "fnc" => array_slice($params, 1), "attr" => $attrs));
+                $inToken = false;
+				$attrs = array();
+            }
+        }
+		if ($attrs !== false)
+			$result[count($result) -1] = array('', array( "value" => "", "fnc" => array(), "attr" => $attrs ));
+        return $result;
+    }
+
+	private function checkAttr($item, $attr)
+	{
+		$attributes = $item->attributes();
+		if ($attr["sep"] == "=")
+			return isset($attributes[$attr["key"]]) && $attributes[$attr["key"]] == $attr["value"];
+		else if ($attr["sep"] === false)
+			return isset($attributes[$attr["key"]]);
+		return false;
+	}
+
+    private function checkQuery($items, &$result, $criteria)
+    {
+        if (empty($criteria))
+        {
+            $result[] = $items;
+            return;
+        }
+        $childCriteria = array_slice($criteria, 1);
+        foreach ($items as $i)
+        {
+            //Check if items match $criteria[0]
+            if (($criteria[0][0] == '' || $criteria[0][0] == '>') && ($i->getName() == $criteria[0][1]["value"] || $criteria[0][1]["value"] == '' || $criteria[0][1]["value"] == '*'))
+            {
+                foreach ($criteria[0][1]["fnc"] as $fnc)
+                {
+                    if (!array_key_exists($fnc, $this->fncList))
+                        throw new Exception("Unexpected token '{$fnc}', expected function name");
+                    //TODO check fnc parameters
+                    //TODO exec fnc
+                }
+				$attr = true;
+				foreach ($criteria[0][1]["attr"] as $attr)
+				{
+					if (!$this->checkAttr($i, $attr))
+					{
+						$attr = false;
+						break;
+					}
+				}
+				if ($attr)
+					$this->checkQuery($i, $result, $childCriteria);
+            }
+            else if ($criteria[0][0] == '')
+                $this->checkQuery($i, $result, $criteria);
+            //TODO ~, +
+        }
+    }
+
+    /**
+     * Find in xml the request
+    **/
+    public function select($criteria_str)
+    {
+        $request = $this->compile($criteria_str);
+		if ($this->debug) { echo "Compiler output: "; var_dump($request); }
+        $result = array();
+        foreach ($request as $i)
+            $this->checkQuery(array($this->xmlNode), $result, $i);
+		$r = array();
+		foreach ($result as $i)
+			$r[] = new self($i);
+		return $r;
+    }
+
+	public function getAttributes()
+	{
+		$result = array();
+		foreach ($this->xmlNode->attributes() as $i => $j)
+			$result[$i] = (string) $j;
+		return $result;
+	}
+
+	public function attr($key =null, $defaultValue =null)
+	{
+		if ($key == null)
+			return $this->getAttributes();
+		if (isset($this->xmlNode->attributes()[$key]))
+			return (string)$this->xmlNode->attributes()[$key];
+		return $defaultValue;
+	}
+
+	public function valueString()
+	{
+		return $this->value;
+	}
+
+	public function __tostring()
+	{
+		return $this->valueString();
+	}
+
+	public function value()
+	{
+		return (string) $this->xmlNode;
+	}
+
+	public function valueFloat()
+	{
+		return (float) $this->value();
+	}
+
+	public function valueDouble()
+	{
+		return (double) $this->value();
+	}
+
+	public function valueInt()
+	{
+		return (int) $this->value();
+	}
+
+	public function parent()
+	{
+		return new self($this->xmlNode->parent());
+	}
+
+    /**
+     * Find in xml the request
+    **/
+    public function __get($name)
+    {
+        return $this->select($name);
+    }
+}
+

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.