ExpatParser.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. <?php
  2. /*
  3. * $Id: ExpatParser.php 905 2010-10-05 16:28:03Z mrook $
  4. *
  5. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  6. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  7. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  8. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  9. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  10. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  11. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  13. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  14. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  15. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16. *
  17. * This software consists of voluntary contributions made by many individuals
  18. * and is licensed under the LGPL. For more information please see
  19. * <http://phing.info>.
  20. */
  21. require_once 'phing/parser/AbstractSAXParser.php';
  22. include_once 'phing/parser/ExpatParseException.php';
  23. include_once 'phing/system/io/IOException.php';
  24. include_once 'phing/system/io/FileReader.php';
  25. /**
  26. * This class is a wrapper for the PHP's internal expat parser.
  27. *
  28. * It takes an XML file represented by a abstract path name, and starts
  29. * parsing the file and calling the different "trap" methods inherited from
  30. * the AbstractParser class.
  31. *
  32. * Those methods then invoke the represenatative methods in the registered
  33. * handler classes.
  34. *
  35. * @author Andreas Aderhold <andi@binarycloud.com>
  36. * @copyright © 2001,2002 THYRELL. All rights reserved
  37. * @version $Revision: 905 $ $Date: 2010-10-05 18:28:03 +0200 (Tue, 05 Oct 2010) $
  38. * @access public
  39. * @package phing.parser
  40. */
  41. class ExpatParser extends AbstractSAXParser {
  42. /** @var resource */
  43. private $parser;
  44. /** @var Reader */
  45. private $reader;
  46. private $file;
  47. private $buffer = 4096;
  48. private $error_string = "";
  49. private $line = 0;
  50. /** @var Location Current cursor pos in XML file. */
  51. private $location;
  52. /**
  53. * Constructs a new ExpatParser object.
  54. *
  55. * The constructor accepts a PhingFile object that represents the filename
  56. * for the file to be parsed. It sets up php's internal expat parser
  57. * and options.
  58. *
  59. * @param Reader $reader The Reader Object that is to be read from.
  60. * @param string $filename Filename to read.
  61. * @throws Exception if the given argument is not a PhingFile object
  62. */
  63. function __construct(Reader $reader, $filename=null) {
  64. $this->reader = $reader;
  65. if ($filename !== null) {
  66. $this->file = new PhingFile($filename);
  67. }
  68. $this->parser = xml_parser_create();
  69. $this->buffer = 4096;
  70. $this->location = new Location();
  71. xml_set_object($this->parser, $this);
  72. xml_set_element_handler($this->parser, array($this,"startElement"),array($this,"endElement"));
  73. xml_set_character_data_handler($this->parser, array($this, "characters"));
  74. }
  75. /**
  76. * Override PHP's parser default settings, created in the constructor.
  77. *
  78. * @param string the option to set
  79. * @throws mixed the value to set
  80. * @return boolean true if the option could be set, otherwise false
  81. * @access public
  82. */
  83. function parserSetOption($opt, $val) {
  84. return xml_parser_set_option($this->parser, $opt, $val);
  85. }
  86. /**
  87. * Returns the location object of the current parsed element. It describes
  88. * the location of the element within the XML file (line, char)
  89. *
  90. * @return object the location of the current parser
  91. * @access public
  92. */
  93. function getLocation() {
  94. if ($this->file !== null) {
  95. $path = $this->file->getAbsolutePath();
  96. } else {
  97. $path = $this->reader->getResource();
  98. }
  99. $this->location = new Location($path, xml_get_current_line_number($this->parser), xml_get_current_column_number($this->parser));
  100. return $this->location;
  101. }
  102. /**
  103. * Starts the parsing process.
  104. *
  105. * @param string the option to set
  106. * @return int 1 if the parsing succeeded
  107. * @throws ExpatParseException if something gone wrong during parsing
  108. * @throws IOException if XML file can not be accessed
  109. * @access public
  110. */
  111. function parse() {
  112. while ( ($data = $this->reader->read()) !== -1 ) {
  113. if (!xml_parse($this->parser, $data, $this->reader->eof())) {
  114. $error = xml_error_string(xml_get_error_code($this->parser));
  115. $e = new ExpatParseException($error, $this->getLocation());
  116. xml_parser_free($this->parser);
  117. throw $e;
  118. }
  119. }
  120. xml_parser_free($this->parser);
  121. return 1;
  122. }
  123. }