首页 > 编程技术 > php

简单的php读取树型xml文件实现类

发布时间:2016-11-25 16:54

XML 函数允许我们解析 XML 文档,但无法对其进行验证。

XML 是一种用于标准结构化文档交换的数据格式。您可以在我们的 XML 教程 中找到更多有关 XML 的信息。

该扩展使用 Expat XML 解析器。

 

<?php教程
     function walk_tree ($node, $depth = 0) {
          for ($i = 0, $indent = ''; $i < $depth; $i++)
               $indent .= '     ';
          if ($node->type == XML_ELEMENT_NODE) {
                print ($indent . $node->tagname . "n");
                $kids = $node->children ();
                $nkids = count ($kids);
                if ($nkids > 0) {
                     $depth++;
                     for ($i = 0; $i < $nkids; $i++)
                          walk_tree ($kids[$i], $depth);
                     $depth--;
               }
          }
     }
     $doc = xmldocfile ('contact.xml');
     print ("<pre>n");
     walk_tree ($doc->root ());
     print ("</pre>n");
?>

<!--
<contact id="43956">
     <personal>
          <name>
               <first>J</first>
               <middle>J</middle>
               <last>J</last>
          </name>
          <title>Manager</title>
          <employer>National</employer>
          <dob>1971-12-22</dob>
     </personal>
</contact>
-->

 

实现,我们经常会用到缓存数据就是把数组保存成xml文档方便处理,下面我们提供一个数组转换成xml文档的类,有需要的朋友可以参考一下。

<?
$elementLevel = 0 ;
function array_Xml($array, $keys = '')
{
global $elementLevel;
if(!is_array($array))
{
if($keys == ''){
return $array;
}else{
return "n<$keys>" . $array . "</$keys>";
}
}else{
foreach ($array as $key => $value)
{
$haveTag = true;
if (is_numeric($key))
{
$key = $keys;
$haveTag = false;
}
/**
* The first element
*/
if($elementLevel == 0 )
{
$startElement = "<$key>";
$endElement = "</$key>";
}
$text .= $startElement."n";
/**
* Other elements
*/
if(!$haveTag)
{
$elementLevel++;
$text .= "<$key>" . array_Xml($value, $key). "</$key>n";
}else{
$elementLevel++;
$text .= array_Xml($value, $key);
}
$text .= $endElement."n";
}
}
return $text;
}
?>

 

class ArrayToXML
{
/**
* The main function for converting to an XML document.
* Pass in a multi dimensional array and this recrusively loops教程 through and builds up an XML document.
*
* @param array $data
* @param string $rootNodeName - what you want the root node to be - defaultsto data.
* @param SimpleXMLElement $xml - should only be used recursively
* @return string XML
*/
public static function toXml($data, $rootNodeName = 'data', $xml=null)
{
// turn off compatibility mode as simple xml throws a wobbly if you don't.
if (ini_get('zend.ze1_compatibility_mode') == 1)
{
ini_set ('zend.ze1_compatibility_mode', 0);
}
if ($xml == null)
{
$xml = simplexml_load_string("<?xml version='1.0' encoding='utf-8'?><$rootNodeName />");
}
// loop through the data passed in.
foreach($data as $key => $value)
{
// no numeric keys in our xml please!
if (is_numeric($key))
{
// make string key...
$key = "unknownNode_". (string) $key;
}
// replace anything not alpha numeric
$key = preg_replace('/[^a-z]/i', '', $key);
// if there is another array found recrusively call this function
if (is_array($value))
{
$node = $xml->addChild($key);
// recrusive call.
ArrayToXML::toXml($value, $rootNodeName, $node);
}
else
{
// add single node.
$value = htmlentities($value);
$xml->addChild($key,$value);
}
}
// pass back as string. or simple xml object if you want!
return $xml->asXML();
}
}


function arrtoxml($arr,$dom=0,$item=0){
if (!$dom){
$dom = new DOMDocument("1.0");
}
if(!$item){
$item = $dom->createElement("root");
$dom->appendChild($item);
}
foreach ($arr as $key=>$val){
$itemx = $dom->createElement(is_string($key)?$key:"item");
$item->appendChild($itemx);
if (!is_array($val)){
$text = $dom->createTextNode($val);
$itemx->appendChild($text);
}else {
arrtoxml($val,$dom,$itemx);
}
}
return $dom->saveXML();
}

php教程 xml处理(利用 xml_parser_create解析、读取、生成)
php处理xml文档有一个xml_parser_create()函数,关于这个函数我们来看一下
xml_parser_create() 函数创建 XML 解析器。

该函数建立一个新的 XML 解析器并返回可被其它 XML 函数使用的资源句柄。

语法
xml_parser_create(encoding)参数 描述
encoding 可选。规定输出编码

 

<?php
     function cdata_handler ($parser, $data) {
        print ($data);
     }
    
     $xml = "<para>some character data</para>";
     $parser = xml_parser_create ();
     xml_set_character_data_handler ($parser, 'cdata_handler');
    
     if (xml_parse ($parser, $xml, true))
          print ("Your XML document is well-formed.");
     else
          print ("Your XML document is not well-formed.");
    
     xml_parser_free ($parser);
?>

实例二

php
     $i = 1;
     function default_handler ($p, $data)
     {
          global $i;
          print ("$i: default: $datan");
          $i++;
     }
    
     function cdata_handler ($p, $data)
     {
          global $i;
          print ("$i: cdata: $datan");
          $i++;
     }
     $xml = "<foo>bar</foo><?exec command ?>";
    
     $p = xml_parser_create ();
     xml_set_default_handler ($p, 'default_handler');
     xml_set_character_data_handler ($p, 'cdata_handler');
    
     if (!xml_parse ($p, $xml, true)){
          die (sprintf ("<br />Parse error in <code>%s</code> (%s)",
                        htmlspecialchars ($xml),
                        xml_error_string (xml_get_error_code ($p))));
     }
     xml_parser_free ($p);
?>

<?php
     function pi_handler ($p, $target, $data) {
        print ($target);
        print ($data);
     }

     $xml = "<?exec ls -l /var?><rootElement/>";
     $p = xml_parser_create ();
     xml_set_processing_instruction_handler ($p, 'pi_handler');
     if (!xml_parse ($p, $xml, true))
          die (sprintf ("Parse error in <code>%s</code> (%s)",
                        htmlspecialchars ($xml),
                        xml_error_string (xml_get_error_code ($p))));
     else
          print ("XML processing complete.n");
     xml_parser_free ($p);
?>

说明
可选参数 encoding 在 PHP 4 中用来指定要被解析的 XML 输入的字符编码方式。

PHP 5 开始,自动侦测输入的 XML 的编码,因此 encoding 参数仅用来指定解析后输出数据的编码。

在 PHP 4 中,默认输出的编码与输入数据的编码是相同的。如果传递了空字符串,解析器会尝试搜索头 3 或 4 个字节以确定文档的编码。

在 PHP 5.0.0 和 5.0.1 中,默认输出的字符编码是 ISO-8859-1,而 PHP 5.0.2 及以上版本是 UTF-8。

解析器支持的编码有 ISO-8859-1, UTF-8 和 US-ASCII。

 

public function parsexml($menus){
2         $result = array();
3         foreach($menus as $menu){
4             $tmparr = array();
5
6             //    处理空文本节点方式a
7             if( $menu->nodename !='#text'){
8
9                 //    检索子元素时跳跃过文本节点  - 处理空文本节点方式b
10                 for($i=1; $i<$menu->childnodes->length; $i+=2) {
11                     $anode = $menu->childnodes->item($i);
12
13                     //    子元素遍历
14                     $anode->childnodes->length > 1 ? $tmparr[$anode->nodename] = $this->parsexml( $anode->childnodes)
15                     : $tmparr[$anode->nodename] = $anode->nodevalue;
16                 }
17                 array_push($result,$tmparr);
18             }
19         }
20         return $result;
21     }
22
23
24
25         $doc = new domdocument();
26         $doc->load ( ‘a.xml’ );
27
28         //    第一种,有空文本节点
29         $menus = $doc->getelementsbytagname('sitemap')->item(0)->childnodes; 
30
31          //    第二种,明确指定标签,序列无空文本节点。但子元素仍然有空节点
32
33         $xpath = new domxpath($doc);
34         $query = "/sitemap/child::a";
35
36         $menus = $xpath->query($query);

 

<books>
<book>
<author>jack herrington</author>
<title>php教程 hacks</title>
<publisher>o'reilly</publisher>
</book>
<book>
<author>jack herrington</author>
<title>podcasting hacks</title>
<publisher>o'reilly</publisher>
</book>
</books>

 1 中的 xml 包含一个图书列表。父标记 <books> 包含一组 <book> 标记,每个 <book> 标记又包含 <author>、<title> 和 <publisher> 标记。
当 xml 文档的标记结构和内容得到外部模式文件的验证后,xml 文档就是正确的。模式文件可以用不同的格式指定。对于本文来说,所需要的只是格式良好的 xml。
如果觉得 xml 看起来很像超文本标记语言(html),那么就对了。xml 和 html 都是基于标记的语言,它们有许多相似之处。但是,要着重指出的是:虽然 xml 文档可能是格式良好的 html,但不是所有的 html 文档都是格式良好的 xml。换行标记(br)是 xml 和 html 之间区别的一个好例子。这个换行标记是格式良好的 html,但不是格式良好的 xml:
<p>this is a paragraph<br>
with a line break</p>
这个换行标记是格式良好的 xml 和 html:
<p>this is a paragraph<br />
with a line break</p>
如果要把 html 编写成同样是格式良好的 xml,请遵循 w3c 委员会的可扩展超文本标记语言(xhtml)标准。所有现代的浏览器都能呈现 xhtml。而且,还可以用 xml 工具读取 xhtml 并找出文档中的数据,这比解析 html 容易得多。
使用 dom 库读取 xml
读取格式良好的 xml 文件最容易的方式是使用编译成某些 php 安装的文档对象模型 (dom)库。dom 库把整个 xml 文档读入内存,并用节点树表示它,如图 1 所示。
图 1. 图书 xml 的 xml dom 树

树顶部的 books 节点有两个 book 子标记。在每本书中,有 author、publisher 和 title 几个节点。author、publisher 和 title 节点分别有包含文本的文本子节点。
读取图书 xml 文件并用 dom 显示内容的代码如清单 2 所示。
清单 2. 用 dom 读取图书 xml
复制代码 代码如下:

<?php
$doc = new domdocument();
$doc->load( 'books.xml' );
$books = $doc->getelementsbytagname( "book" );
foreach( $books as $book )
{
$authors = $book->getelementsbytagname( "author" );
$author = $authors->item(0)->nodevalue;
$publishers = $book->getelementsbytagname( "publisher" );
$publisher = $publishers->item(0)->nodevalue;
$titles = $book->getelementsbytagname( "title" );
$title = $titles->item(0)->nodevalue;
echo "$title - $author - $publishern";
}
?>

标签:[!--infotagslink--]

您可能感兴趣的文章: