XML 파싱(xml2array)
페이지 정보
작성자 MintState 댓글 0건 조회 16,140회 작성일 09-08-27 14:54본문
XML 파싱(xml2array)
몇가지 xml parser를 찾아 봤는데 딱 마음에 드는것은 없네요..
아래는 http://www.bin-co.com/php/scripts/xml2array/ 에서 공개된 xml2array 소스입니다.
추가 :
괜찮은 소스가 있어서 추가 합니다. 클레스로 되어있네요.
http://www.phpbuilder.com/snippet/detail.php?id=868&type=snippet
몇가지 xml parser를 찾아 봤는데 딱 마음에 드는것은 없네요..
아래는 http://www.bin-co.com/php/scripts/xml2array/ 에서 공개된 xml2array 소스입니다.
<?php
/**
* xml2array() will convert the given XML text to an array in the XML structure.
* Link: http://www.bin-co.com/php/scripts/xml2array/
* Arguments : $contents - The XML text
* $get_attributes - 1 or 0. If this is 1 the function will get the attributes as well as the tag values - this results in a different array structure in the return value.
* $priority - Can be 'tag' or 'attribute'. This will change the way the resulting array sturcture. For 'tag', the tags are given more importance.
* Return: The parsed XML in an array form. Use print_r() to see the resulting array structure.
* Examples: $array = xml2array(file_get_contents('feed.xml'));
* $array = xml2array(file_get_contents('feed.xml', 1, 'attribute'));
*/
function xml2array($contents, $get_attributes=1, $priority = 'tag') {
if(!$contents) return array();
if(!function_exists('xml_parser_create')) {
//print "'xml_parser_create()' function not found!";
return array();
}
//Get the XML parser of PHP - PHP must have this module for the parser to work
$parser = xml_parser_create('');
@xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "euc-kr"); # http://minutillo.com/steve/weblog/2004/6/17/php-xml-and-character-encodings-a-tale-of-sadness-rage-and-data-loss
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
xml_parse_into_struct($parser, trim($contents), $xml_values);
xml_parser_free($parser);
if(!$xml_values) return;//Hmm...
//Initializations
$xml_array = array();
$parents = array();
$opened_tags = array();
$arr = array();
$current = &$xml_array; //Refference
//Go through the tags.
$repeated_tag_index = array();//Multiple tags with same name will be turned into an array
foreach($xml_values as $data) {
unset($attributes,$value);//Remove existing values, or there will be trouble
//This command will extract these variables into the foreach scope
// tag(string), type(string), level(int), attributes(array).
extract($data);//We could use the array by itself, but this cooler.
$result = array();
$attributes_data = array();
if(isset($value)) {
if($priority == 'tag') $result = $value;
else $result['value'] = $value; //Put the value in a assoc array if we are in the 'Attribute' mode
}
//Set the attributes too.
if(isset($attributes) and $get_attributes) {
foreach($attributes as $attr => $val) {
if($priority == 'tag') $attributes_data[$attr] = $val;
else $result['attr'][$attr] = $val; //Set all the attributes in a array called 'attr'
}
}
//See tag status and do the needed.
if($type == "open") {//The starting of the tag '<tag>'
$parent[$level-1] = &$current;
if(!is_array($current) or (!in_array($tag, array_keys($current)))) { //Insert New tag
$current[$tag] = $result;
if($attributes_data) $current[$tag. '_attr'] = $attributes_data;
$repeated_tag_index[$tag.'_'.$level] = 1;
$current = &$current[$tag];
} else { //There was another element with the same tag name
if(isset($current[$tag][0])) {//If there is a 0th element it is already an array
$current[$tag][$repeated_tag_index[$tag.'_'.$level]] = $result;
$repeated_tag_index[$tag.'_'.$level]++;
} else {//This section will make the value an array if multiple tags with the same name appear together
$current[$tag] = array($current[$tag],$result);//This will combine the existing item and the new item together to make an array
$repeated_tag_index[$tag.'_'.$level] = 2;
if(isset($current[$tag.'_attr'])) { //The attribute of the last(0th) tag must be moved as well
$current[$tag]['0_attr'] = $current[$tag.'_attr'];
unset($current[$tag.'_attr']);
}
}
$last_item_index = $repeated_tag_index[$tag.'_'.$level]-1;
$current = &$current[$tag][$last_item_index];
}
} elseif($type == "complete") { //Tags that ends in 1 line '<tag />'
//See if the key is already taken.
if(!isset($current[$tag])) { //New Key
$current[$tag] = $result;
$repeated_tag_index[$tag.'_'.$level] = 1;
if($priority == 'tag' and $attributes_data) $current[$tag. '_attr'] = $attributes_data;
} else { //If taken, put all things inside a list(array)
if(isset($current[$tag][0]) and is_array($current[$tag])) {//If it is already an array...
// ...push the new element into that array.
$current[$tag][$repeated_tag_index[$tag.'_'.$level]] = $result;
if($priority == 'tag' and $get_attributes and $attributes_data) {
$current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data;
}
$repeated_tag_index[$tag.'_'.$level]++;
} else { //If it is not an array...
$current[$tag] = array($current[$tag],$result); //...Make it an array using using the existing value and the new value
$repeated_tag_index[$tag.'_'.$level] = 1;
if($priority == 'tag' and $get_attributes) {
if(isset($current[$tag.'_attr'])) { //The attribute of the last(0th) tag must be moved as well
$current[$tag]['0_attr'] = $current[$tag.'_attr'];
unset($current[$tag.'_attr']);
}
if($attributes_data) {
$current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data;
}
}
$repeated_tag_index[$tag.'_'.$level]++; //0 and 1 index is already taken
}
}
} elseif($type == 'close') { //End of tag '</tag>'
$current = &$parent[$level-1];
}
}
return($xml_array);
}
?>
추가 :
괜찮은 소스가 있어서 추가 합니다. 클레스로 되어있네요.
http://www.phpbuilder.com/snippet/detail.php?id=868&type=snippet
<?php
/**
* =============================================================
* The simple class for parse XML content to PHP array.
* Version : 1.0.1
* Last Upd : Thu Jan 30 14:51:18 GMT 2003
* Created By : Heiko Mundle [hmundle1@gmx.net]
* New Features: reads all attributes of a xml tag
* doesn't overwrite tags with same tag name (and same tag attribute)
*
* The simple class for parse XML content to PHP array.
* Version : 1.0
* Last Upd : Thu Oct 24 11:51:18 GMT 2002
* Created By : Phairote Charoen [phairotec@hotmail.com]
* =============================================================
* This XML content must specific some attribute for the key of record.
* <root>
* <item id="1" class="myclass">
* <name>xxxx</name>
* <price>100</price>
* </item>
* more content
* </root>
*
* Result :
*Array
*(
* [0] => Array
* (
* [name] => root
* [attr] => Array
* (
* )
* [cont] => Array
* (
* [0] => Array
* (
* [name] => item
* [attr] => Array
* (
* [id] => 1
* [class] => myclass
* )
* [cont] => Array
* (
* [0] => Array
* (
* [name] => name
* [attr] => Array
* (
* )
* [cont] => Array
* (
* [0] => xxxx
* )
* )
* [1] => Array
* (
* [name] => price
* [attr] => Array
* (
* )
* [cont] => Array
* (
* [0] => 100
* )
* )
* )
* )
* [1] => more content
* )
* )
*)
*
*/
define(WRITE_FLAG_NOT_NULL, 1);
define(WRITE_FLAG_NULL, 2);
define(WRITE_FLAG_EMPTY_ARRAY, 4);
class Xml2Array
{
/**
* The XML file name( can be also real path and web url ).
*/
var $xmlFile;
/**
* The array result from this class.
*/
var $arrResult = array();
/**
* The key stack, I keep each tag name of each level to stack array.
*/
var $keyStack = array();
/**
* Deep of stack array.
*/
var $stackIndex = 0;
/**
* The XML Parser ..
*/
var $parser;
/**
* The constructor.
* @xmlFile (string) - XML source file name
*/
function Xml2Array($xmlFile)
{
$this->xmlFile = $xmlFile;
$this->parser = xml_parser_create();
xml_set_object($this->parser, &$this);
xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false);
xml_parser_set_option($this->parser, XML_OPTION_SKIP_WHITE,true);
xml_set_element_handler($this->parser, "startElement", "endElement");
xml_set_character_data_handler($this->parser, "characterData");
}
/**
* start element handler
*/
function startElement($parser, $name, $atts)
{
$name = trim($name);
$txt = "\$arr = " . $this->getArrayName($this->stackIndex) . ";";
eval($txt);
$this->keyStack[$this->stackIndex] = count($arr);
$this->stackIndex++;
$this->writeData("", WRITE_FLAG_EMPTY_ARRAY);
if(!empty($name))
{
// using the element name to array key..
$this->keyStack[$this->stackIndex] = "'name'";
$this->stackIndex++;
$this->writeData($name, WRITE_FLAG_NULL);
$this->stackIndex--;
$this->keyStack[$this->stackIndex] = "'attr'";
$this->stackIndex++;
if(!empty($atts))
{
// using the attributes to array key..
foreach($atts as $attKey => $attVal)
{
$this->keyStack[$this->stackIndex] = "'".$attKey."'";
$this->stackIndex++;
$this->writeData($attVal, WRITE_FLAG_NULL);
$this->stackIndex--;
}
}
else
{
$this->writeData("", WRITE_FLAG_EMPTY_ARRAY);
}
$this->stackIndex--;
$this->keyStack[$this->stackIndex] = "'cont'";
$this->stackIndex++;
}
}
/**
* end element handler
*/
function endElement($parser, $name)
{
$this->stackIndex-=2;
}
/**
* none tag element handler
*/
function characterData($parser, $data)
{
$data = trim($data);
if(!empty($data))
{
$txt = "\$arr = " . $this->getArrayName($this->stackIndex) . ";";
eval($txt);
$this->keyStack[$this->stackIndex] = count($arr);
$this->stackIndex++;
$this->writeData($data, WRITE_FLAG_NOT_NULL);
$this->stackIndex--;
}
}
/**
* write data in array
*/
function writeData($data, $flag)
{
$data = trim($data);
$dataStr = "\"" . $data . "\"";
switch( $flag )
{
case WRITE_FLAG_NOT_NULL:
default:
// stop if there isn't any data
if(empty($data))
break;
case WRITE_FLAG_EMPTY_ARRAY:
// overwrite default dataStr
if(empty($data))
$dataStr = "array()";
case WRITE_FLAG_NULL:
$txt = $this->getArrayName($this->stackIndex)." = ".$dataStr.";";
// assign value to the result array ..
eval($txt);
break;
}
}
/**
* get name of array
*/
function getArrayName($depth)
{
if($depth)
{
for($i=0; $i<$depth; $i++)
{
$key .= $this->keyStack[$i]."|";
}
$key = preg_replace("/\|$/", "]", $key);
$key = preg_replace("/\|/", "][", $key);
return "\$this->arrResult[".$key;
}
else
{
return "\$this->arrResult";
}
}
/**
* parsing ..
*/
function parse()
{
if (!($fp = fopen($this->xmlFile, "r")))
{
die("Could not open XML input!");
}
while ($data = fread($fp, 4096))
{
if (!xml_parse($this->parser, $data, feof($fp)))
{
die(sprintf("XML error: %s at line %d", xml_error_string(xml_get_error_code($this->parser)),xml_get_current_line_number($this->parser)));
}
}
fclose($fp);
}
/**
* @return the result array
*/
function getResult()
{
return $this->arrResult;
}
/**
* free the XML parser result ..
*/
function freeResult()
{
xml_parser_free($this->parser);
}
} // end class
?>
<?php // Testing the clsXml2Array class. $xmlFile = "test.xml"; $r = new clsXml2Array($xmlFile); $r->parse(); $arrResult = $r->getResult(); $r->freeResult(); echo "<PRE>"; print_r($arrResult); echo "</PRE>"; ?>
|
|
댓글목록
등록된 댓글이 없습니다.





XML 파싱(xml2array)