php读取xml文件的三种实现方法

 更新时间:2016年11月25日 16:54  点击:1795
文章介绍了三种方式来读取xml文件分别是new DOMDocument(),正则解析xml,用parser函数来读取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 - $publisher/n";
  }
  ?>


正则解析

 代码如下 复制代码
<?php
  $xml = "";
  $f = fopen( 'books.xml', 'r' );
  while( $data = fread( $f, 4096 ) ) { $xml .= $data; }
  fclose( $f );
 
  preg_match_all( "//<book/>(.*?)/<//book/>/s",
  $xml, $bookblocks );
 
  foreach( $bookblocks[1] as $block )
  {
  preg_match_all( "//<author/>(.*?)/<//author/>/",
  $block, $author );
  preg_match_all( "//<title/>(.*?)/<//title/>/",
  $block, $title );
  preg_match_all( "//<publisher/>(.*?)/<//publisher/>/",
  $block, $publisher );
  echo( $title[1][0]." - ".$author[1][0]." - ".
  $publisher[1][0]."/n" );
  }
  ?>


books.xml文件如下

 代码如下 复制代码
<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>


下面就给大家举一个小小的例子用parser函数来读取xml数据:

 

 代码如下 复制代码

<?php
$parser = xml_parser_create(); //创建一个parser编辑器
xml_set_element_handler($parser, "startElement", "endElement");//设立标签触发时的相应函数 这里分别为startElement和endElenment
xml_set_character_data_handler($parser, "characterData");//设立数据读取时的相应函数
$xml_file="1.xml";//指定所要读取的xml文件,可以是url
$filehandler = fopen($xml_file, "r");//打开文件

 


while ($data = fread($filehandler, 4096))
{
    xml_parse($parser, $data, feof($filehandler));
}//每次取出4096个字节进行处理

fclose($filehandler);
xml_parser_free($parser);//关闭和释放parser解析器


$name=false;
$position=false;
function startElement($parser_instance, $element_name, $attrs)        //起始标签事件的函数
 {
   global $name,$position; 
   if($element_name=="NAME")
   {
   $name=true;
   $position=false;
   echo "名字:";
  }
  if($element_name=="POSITION")
   {$name=false;
   $position=true;
   echo "职位:";
  }
}

function characterData($parser_instance, $xml_data)                  //读取数据时的函数
{
   global $name,$position;
   if($position)
    echo $xml_data."<br>";
    if($name)
     echo $xml_data."<br>";
}

function endElement($parser_instance, $element_name)                 //结束标签事件的函数
{
 global $name,$position;
$name=false;
$position=false; 
}

?>

xml文件代码如下:

 

 代码如下 复制代码

<?xml version="1.0"?>
<employees>
<employee>
<name>张三</name>
<position age="45">经理</position>
</employee>
<employees>
<employee>
<name>李四</name>
<position age="45">助理</position>
</employee>
</employees>

parser是php内置的一个用来处理xml的解析器,它的工作由三个事件组成:起始标签、 读取数据、结束标签。

也就是说在对xml进行处理的时候每当遇到起始标签、数据和结束标签的时候函数会做相应的动作来完成对xml数据的转换。

文章从最基础的什么是xml到最终于用实例告诉你如何利用php来读,写,删除,编辑xml文档,是一篇不错的xml讲解文档,有需要的同学可以收藏本文章。

什么是XML?
XML(eXtensible Markup Language)是国际标准化组织的标准通用标记语言SGML的子集。由以下规范组成:

可扩展样式语言(eXtensible Sytle Language , XSL)
XML链接语言(XML Linking Language,包括Xpath、Xlink和Xpointer)
XML名称空间(XML Namespace)
在PHP5之前的版本对XML的处理存在很多的问题,例如XML工具之间只具有简单的关联、每个工具不能一起协同工作等,PHP5中的新XML扩展具有下列特点:

能够像一个整体一样协调工作
是一个标准化的XML库:libxml2
完全遵循W3C规范
更有效地处理数据
是你工作中合适的XML工具
HTML和XML区别与联系?
HTML和XML都是SGML的子集,所以他们有很大的相似性。下面是XML相对于HTML具有的独特性:

可扩展性,用以定义需要的新标记。这对于今天的web是很有意义的
结构,用于表示任意复杂程度的数据。从某种意义上说是一个小型的关系数据库
校验,用以检查数据的结构正确性。通过DTD约束可以达到这一目的。
媒体无关性,以多种格式发布内容。网页、手机显示的wml、其他媒体终端的显示等
厂商和平台中立
数据的表示与内容分离(这是与html本质区别,但现在流行的DIV+CSS设计思路与这种近似)
XML的元素区分大小写
任何元素都需要有结束标记
XML只有一个根元素
属性必须加上引号
一个完整的XML长什么样子?

 代码如下 复制代码
<?xml version="1.0"?>
<shows>
    <show>
        <name>Simpsons</name>
        <channel>FOX</channel>
        <start>8:00 PM</start>
        <duration>30</duration>
    </show>
    <show>
        <name>Law & Order</name>
        <channel>NBC</channel>
        <start>8:00 PM</start>
        <duration>60</duration>
    </show>
</shows>

  

形式良好的XML文档须具备下列特征:

每一个元素有一个开始和结束标记
文档有且只有一个根元素,其他的所有元素都是它的子元素
正确的格式化空元素
标记的大小写匹配
正确的嵌套
属性值必须用引号
实体在引用之前必须声明
实体不能循环指向自身
通过DOM生成XML
 

 代码如下 复制代码

// 创建一个新的文档$dom = new DOMDocument('1.0');
// 创建一个根元素<book>并将其添加到文档$book = $dom->appendChild($dom->createElement('book'));
// 创建一个title子元素,并添加到$book中
$title = $book->appendChild($dom->createElement('title'));
// 设置title元素的文本及cover属性
$title->appendChild($dom->createTextNode('PHP Cookbook'));
$title->setAttribute('cover', 'soft');
// 创建并将author元素添加到$book中
$sklar = $book->appendChild($dom->createElement('author'));
//添加文本到author节点$sklar->appendChild($dom->createTextNode('Sklar'));

$trachtenberg = $book->appendChild($dom->createElement('author'));
$trachtenberg->appendChild($dom->createTextNode('Trachtenberg'));

// 输出完美格式化的XML文档$dom->formatOutput = true;
echo $dom->saveXML();输出内容如下:

 代码如下 复制代码
<?xml version="1.0"?>
<book?>
  <cover="soft">PHP Cookbook</title>
</book>

用PHP解析已经存在的XML文件
常用有三种方式来解析XML文件

对于简单文件采用SimpleXML
对于复杂的XML文件采用DOM扩展来实现
对于大型XML文件采用XMLReader扩展来实现
XML示例文件如下(address-book.xml):

 代码如下 复制代码

<?xml version="1.0"?>
<address-book>
    <person id="1">
        <!--David Sklar-->
        <firstname>David</firstname>
        <lastname>Sklar</lastname>
        <city>New York</city>
        <state>NY</state>
        <email>sklar@php.net</email>
    </person>

    <person id="2">
        <!--Adam Trachtenberg-->
        <firstname>Adam</firstname>
        <lastname>Trachtenberg</lastname>
        <city>San Francisco</city>
        <state>CA</state>
        <email>amt@php.net</email>
    </person>
</address-book>

  

通过SimpleXML方式:

 代码如下 复制代码

$sx = simplexml_load_file('address-book.xml');

foreach ($sx->person as $person) {
    $firstname_text_value = $person->firstname;
    $lastname_text_value = $person->lastname;

    print "$firstname_text_value $lastname_text_valuen";

}通过DOM扩展:

 

 代码如下 复制代码

$dom = new DOMDocument;
$dom->load('address-book.xml');

foreach ($dom->getElementsByTagname('person') as $person) {
    $firstname = $person->getElementsByTagname('firstname');
    $firstname_text_value = $firstname->item(0)->firstChild->nodeValue;

    $lastname = $person->getElementsByTagname('lastname');
    $lastname_text_value = $lastname->item(0)->firstChild->nodeValue;

    print "$firstname_text_value $lastname_text_valuen";
}

通过XMLReader扩展:

 代码如下 复制代码

$reader = new XMLReader();
$reader->open('card-catalog.xml');

while ($reader->read()) {
    if ($reader->nodeType == XMLREADER::ELEMENT && $reader->localName == 'author') {
        $reader->read();
        print $reader->value . "n";
    }
}

用XPath来查询信息http://www.111cn.net
在SimpleXML和DOM扩展中都有XPath

 代码如下 复制代码

//SimpleXml示例
$emails = $s->xpath('/address-book/preson/email');

//DOM扩展示例

 代码如下 复制代码
$xpath = new DOMXPath($dom);
$email = $xpath->query('/address-book/preson/email');验证XML文档是否合法

在PHP中,DOM扩展支持基于DTD,XML Schema和RelaxNG的验证,而SimpleXML则只提供了XML Schema验证。

XML内容为UTF-8格式
如果数据来源为其他格式,需要经过编码为UTF-8格式,下面是通过iconv库进行转换的示例

 代码如下 复制代码

$utf_8 = iconv('ISO-8859-1', 'UTF-8', $iso_8859_1);

前面的mysql.php 是封装的mysql数据库功能,单例模式,所以取对象是静态方法 mysql::getObject(); 代码很简单
 代码如下 复制代码

include 'mysql.php';
$mysql= mysql::getObject();
$mysql->query("SELECT * FROM post");


$xml = new XMLWriter();

$xml->openUri('hello.xml'); //  or 'php://output'

$xml->setIndentString('   ');
$xml->setIndent(true);
// start
$xml->startDocument('1.0', 'UTF-8');

// <rss version="2.0">
$xml->startElement('rss');
   $xml->writeAttribute('version','2.0');
  
 // <channel>
 $xml->startElement('channel');
     // title
     $xml->startElement('title');
          $xml->text('title');
     $xml->endElement();
     // link
     $xml->startElement('link');
          $xml->text('http://foodstory.me/post/');
     $xml->endElement();
     // description
     $xml->startElement('description');
          $xml->text('');
     $xml->endElement();
     // language
     $xml->startElement('language');
          $xml->text('zh-cn');
     $xml->endElement();
     // category
     $xml->startElement('category');
          $xml->text('IT');
     $xml->endElement();
     // copyright
     $xml->startElement('copyright');
          $xml->text('copyright 2011 foodstory.me');
     $xml->endElement();

     // for item
     while( $row = $mysql->fetch() )
     {
      $xml->startElement('item');
         // title
        $xml->startElement('title');
             $xml->text( $row['title']);
        $xml->endElement();
        // link
        $xml->startElement('link');
             $xml->text( 'http://foodstory.me/post/'.$row['id'].'.html');
        $xml->endElement();
        // description
        $xml->startElement('description');
             $xml->text( $row['text'] );
        $xml->endElement();
        // pubDate
        $xml->startElement('pubDate');
             $xml->text( date('D, d M Y H:i:s T', $row['time']) );
        $xml->endElement();
       
        // category tag author need to write .over
      $xml->endElement(); // item
     }
 $xml->endElement(); // channel
$xml->endElement();  // rss

$xml->endDocument();
// $xml->flush();

openUri('') 方法的参数可以是一个文件,那么xml数据就写入到这个文件
或者 php://output 输出到缓冲区,然后 flush方法输出到页面

与大多数流行的 Web 服务如 twitter 通过开放 API 来提供数据一样,它总是能够知道如何解析 API 数据的各种传送格式,包括 JSON,XML 等等。

$json_string='{"id":1,"name":"foo","email":"foo@foobar.com","interest":["wordpress","php教程"]} ';
$obj=json_decode($json_string);
echo $obj->name; //prints foo
echo $obj->interest[1]; //prints php
PHP解析XML 数据

$xml_string="<?xml version='1.0'?>
<users>
<user id='398'>
<name>Foo</name>
<email>foo@bar.com</name>
</user>
<user id='867'>
<name>Foobar</name>
<email>foobar@foo.com</name>
</user>
</users>";

//load the xml string using simplexml
$xml = simplexml_load_string($xml_string);

//loop through the each node of user
foreach ($xml->user as $user)
{
//access attribute
echo $user['id'], ' ';
//subnodes are accessed by -> operator
echo $user->name, ' ';
echo $user->email, '<br />';
}

实现,我们经常会用到缓存数据就是把数组保存成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();
}

[!--infotagslink--]

相关文章

  • php抓取网站图片并保存的实现方法

    php如何实现抓取网页图片,相较于手动的粘贴复制,使用小程序要方便快捷多了,喜欢编程的人总会喜欢制作一些简单有用的小软件,最近就参考了网上一个php抓取图片代码,封装了一个php远程抓取图片的类,测试了一下,效果还不错分享...2015-10-30
  • C#从数据库读取图片并保存的两种方法

    这篇文章主要介绍了C#从数据库读取图片并保存的方法,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...2021-01-16
  • mysql 批量更新与批量更新多条记录的不同值实现方法

    批量更新mysql更新语句很简单,更新一条数据的某个字段,一般这样写:复制代码 代码如下:UPDATE mytable SET myfield = 'value' WHERE other_field = 'other_value';如果更新同一字段为同一个值,mysql也很简单,修改下where即...2013-10-04
  • php把读取xml 文档并转换成json数据代码

    在php中解析xml文档用专门的函数domdocument来处理,把json在php中也有相关的处理函数,我们要把数据xml 数据存到一个数据再用json_encode直接换成json数据就OK了。...2016-11-25
  • EXCEL数据上传到SQL SERVER中的简单实现方法

    EXCEL数据上传到SQL SERVER中的方法需要注意到三点!注意点一:要把EXCEL数据上传到SQL SERVER中必须提前把EXCEL传到服务器上.做法: 在ASP.NET环境中,添加一个FileUpload上传控件后台代码的E.X: 复制代码 代码如下: if...2013-09-23
  • c# 对CSV文件操作(写入、读取、修改)

    这篇文章主要介绍了c# 如何对CSV文件操作,帮助大家更好的理解和学习C#,感兴趣的朋友可以了解下...2020-11-03
  • python读取和保存mat文件的方法

    本文主要介绍了python读取和保存mat文件的方法,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-08-25
  • jQuery读取XML文件的方法示例

    这篇文章主要介绍了jQuery读取XML文件的方法,结合实例形式分析了jQuery基于ajax针对xml文件的读取操作相关技巧,需要的朋友可以参考下...2017-02-08
  • Android中使用SDcard进行文件的读取方法

    首先如果要在程序中使用sdcard进行存储,我们必须要在AndroidManifset.xml文件进行下面的权限设置: 在AndroidManifest.xml中加入访问SDCard的权限如下: <!--...2016-09-20
  • PHP翻页跳转功能实现方法

    我们都知道用php+mysql在web 页实现数据库资料全部显示是非常简单而有趣的,数据库资料很少的情况下页面显示还是让人满意的,但是当数据库资料非常多的情况下,页面的显示情况将会变的非常糟糕,下面就来介绍一下如何实现当...2015-11-08
  • 网页自动调用国内双核浏览器的极速模式的实现方法

    由于国内好几个浏览器都是双核浏览器(蛋痛,做一个浏览器壳就说国产,而且使用率高),有时打开网页会出现不兼容模式,在极速模式下是好的,现在我们来用代码实现网页自动调用国内...2016-09-20
  • perl大文件读取处理的模块介绍

    perl CPAN中有一个Tie-File 模块极大方便了对大文件的操作...2020-06-29
  • 使用MSScriptControl 在 C# 中读取json数据的方法

    下面小编就为大家带来一篇使用MSScriptControl 在 C# 中读取json数据的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
  • C#实现appSettings节点读取与修改的方法

    这篇文章主要介绍了C#实现appSettings节点读取与修改的方法,是非常实用的技巧,需要的朋友可以参考下...2020-06-25
  • golang文件读取-按指定BUFF大小读取方式

    这篇文章主要介绍了golang文件读取-按指定BUFF大小读取方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-12-22
  • Java读取PDF中的表格的方法示例

    本文主要介绍了Java读取PDF中的表格的方法示例,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-10-22
  • R语言读取csv文件出错的解决方案

    这篇文章主要介绍了R语言读取csv文件出错的解决方案,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-05-06
  • php读取本地php文件源代码输出显示

    下在看一个利用fopen,file_get_contents读取本地服务器中.php文件的代码并显示的一些方法总结 如我有两个文件a.php,b.php。 a.php文件中的语句是: 代码如...2016-11-25
  • Windows系统中使用C#读取文本文件内容的小示例

    这篇文章主要介绍了Windows系统中使用C#读取文本文件内容的小示例,包括一次一行地读取文本文件的方法,需要的朋友可以参考下...2020-06-25
  • Java解析xml文件遇到特殊符号异常的情况(处理方案)

    这篇文章主要介绍了Java解析xml文件遇到特殊符号&会出现异常的解决方案,实现思路很简单通过在读取xml文件使用SAX解析前读取reader,具体实现方法及示例代码跟随小编一起看看吧...2021-05-14