PHP Advanced and Object-Oriented Programming: Visual QuickPro Guide. 在实际操作XML前,先简单介绍一下SimpleXML包含" />

PHP操作XML方法之SimpleXML

来源:博客园 分类: 文章浏览史 发布时间:2020-11-27 16:19:30 最后更新:2020-11-27 浏览:201
转载声明:
本文为摘录自“博客园”,版权归原作者所有。
温馨提示:
为了更好的体验,请点击原文链接进行浏览
摘录时间:
2020-11-27 16:19:30

SimpleXML简介

SimpleXML 扩展提供了一个非常简单和易于使用的工具集,能将XML转换成一个带有一般属性选择器和数组迭代器的对象。

举例XML

XML结构部分引用自<<深入理解PHP>>,并且为了说明某个方法的使用,强行增加一些看似根本用不合理的结构

我将用该XML结构完成:

<?xml version="1.0" encoding="utf-8"?>
<collection xmlns:lan="language">
    <php:book xmlns:php="php">
        <php:title php:edition="3">PHP Advanced and Object-Oriented Programming: Visual QuickPro Guide</php:title>
        <author:author xmlns:author="LarryUllman">Larry Ullman</author:author>
        <php:year>2012</php:year>
        <php:pages>612</php:pages>
        <php:chapterArr>
          <php:chapter php:number="12">PHP's Command-Line Interface</php:chapter>
          <php:chapter php:number="13">XML and PHP</php:chapter>
          <php:chapter php:number="14">Debugging, Testing, and Performance</php:chapter>
        </php:chapterArr>
        <php:cover php:fileName="phpvqp3.jpg"/>
    </php:book>
    <js:book xmlns:js="javascript">
        <js:title>Modern JavaScript: Develop and Design</js:title>
        <author:author  xmlns:author="LarryUllman">Larry Ullman</author:author>
        <js:year>2012</js:year>
        <js:pages>504</js:pages>
        <js:chapterArr>
          <js:chapter js:number="1" js:pages="24">(Re-)Introducing JavaScript</js:chapter>
          <js:chapter js:number="2" js:pages="32">JavaScript in Action</js:chapter>
          <js:chapter js:number="3" js:pages="34">Tools of the Trade</js:chapter>
        </js:chapterArr>
    </js:book>
</collection>

类方法及函数

在实际操作(增,删,改,查)XML前,先简单介绍一下SimpleXML包含的方法和函数对应的功能,如果你对此有一定的了解,可以跳本部分,直接看:生成XML操作读取XML操作更新XML操作删除XML操作的例子。

** PS:本文不会对方法和函数的功能及参数做详细介绍(因为都已尽量体现在操作中),如想了解更多,请参考官网。 **

方法

  • addAttribute 为SimpleXML元素添加一个属性
  • addChild 为SimpleXML节点增加一个子节点
  • asXML 返回一个基于SimpleXML对象没有语法错误的XML字符串
  • attributes 识别元素的的所有属性
  • children 返回给定节点的子节点
  • __construct 创建SimpleXML对象的初始化方法
  • count 计算元素子节点个数
  • getDocNamespaces 获取XML文档中申明的命名空间
  • getName 获取SimpleXML节点的元素名
  • getNamespaces 获取XML文档中使用过的命名空间
  • registerXPathNamespace 为XPath查询创建一个前缀或者命名空间
  • saveXML asXML的别名
  • __toString 魔术方法,返回SimpleXML节点的字符串内容
  • xpath 运行一个xpath查询

函数

  • simplexml_import_dom 把一个DOM对象转换为一个SimpleXML对象
  • simplexml_load_file 把一个XML文件解析为一个SimpleXML对象
  • simplexml_load_string 把一个字符串解析为一个SimpleXML对象

SimpleXML操作XML

生成XML

<?php 
//定义数据
$bookArr = [
    [
        'book'  => [
            'value' => null,
            'attr'  => [
                'nsKey'     => 'program:xmlns:php',
                'nsVal'     => 'php',
            ],
        ],
        'title'     =>
        [
            'value' => 'PHP Advanced and Object-Oriented Programming: Visual QuickPro Guide',
            'attr'  => [
                'edition' => 3
            ]
        ],
        'author'    => 'Larry Ullman',
        'year'      => 2012,
        'pages'     => 612,
        'chapterArr'=>
        [
            [
                'value' => 'PHP&apos;s Command-Line Interface',
                'attr'  => ['number'=>12]
            ],
            [
                'value' => 'XML and PHP',
                'attr'  => ['number'=>13]
            ],
            [
                'value' => 'Debugging, Testing, and Performance',
                'attr'  => ['number'=>14]
            ],
        ],
        'cover'   => [
            'attr'    => ['fileName'=>'phpvqp3.jpg'],
        ]
    ],
    [
        'book'  => [
            'value'  => null,  
            'attr'   => [
                'nsKey' => 'program:xmlns:js',
                'nsVal' => 'javascript',
            ]
        ],
        'title'     => ['value'=>'Modern JavaScript: Develop and Design'],
        'author'    => 'Larry Ullman',
        'year'      => 2012,
        'pages'     => 504,
        'chapterArr'=> [
            [
                'value' => '(Re-)Introducing JavaScript',
                'attr'  => ['number'=>1, 'pages'=>24]
            ],
            [
                'value' => 'JavaScript in Action',
                'attr'  => [ 'number'=>2, 'pages'=>32]
            ],
            [
                'value' => 'Tools of the Trade',
                'attr'  => ['number'=>3,'pages'=>34]
            ]
        ]
    ]
];

//用一段字符串生成一个XML的root节点
$statement = '<?xml version="1.0" encoding="utf-8"?><collection xmlns:lan="language"></collection>';
$rootXML = simplexml_load_string($statement); //等价于 $rootXML = new SimpleXMLElement($statement);

foreach($bookArr as $book){
    //获取数组中定义的节点的命名空间,如program:xmlns:php,则php为元素的前缀
    $tempPrefix = substr($book['book']['attr']['nsKey'],strpos($book['book']['attr']['nsKey'], ':') + 1);
    $prefix = $tempPrefix ? $tempPrefix . ':' : '';

    //为root节点添加一个带有指定命名空间的book节点
    $bookNode = $rootXML->addChild($prefix.'book',$book['book']['value']);

    //定义book节点的命名空间及前缀
    $bookNode->addAttribute($book['book']['attr']['nsKey'],$book['book']['attr']['nsVal']);

    //为book节点添加一个带有指定命名空间,指定值的title节点
    $titleNode = $bookNode->addChild($prefix.'title',$book['title']['value']);

    //为title节点增加指定命名空间及属性
    if(!empty($book['title']['attr'])){
        foreach($book['title']['attr'] as $k => $v){
            $titleNode->addAttribute($prefix.$k,$v);
        }
    }

    //为book节点添加一个子节点author及值
    $authorNode = $bookNode->addChild('author',$book['author']);
    //为author节点设置命名空间及前缀
    $authorNode->addAttribute('program:xmlns:author','LarryUllman');

    //为book节点添加一个子节点year及值
    $bookNode->addChild($prefix.'year',$book['year']);

    //为book节点添加一个子节点pages及值
    $bookNode->addChild($prefix.'pages',$book['pages']);

    //为book节点增加一个指定命名空间的chapterArr节点
    $chapterArr = $bookNode->addChild($prefix.'chapterArr');

    //为chapterArr节点增加一个指定命名空间,指定值指定属性的chapter节点
    if(!empty($book['chapterArr'])){
        foreach($book['chapterArr'] as $value){
            $chapterNode = $chapterArr->addChild($prefix.'chapter',$value['value']);
            if(!empty($value['attr'])) {
                foreach ($value['attr'] as $k => $v) {
                    $chapterNode->addAttribute($prefix . $k, $v);
                }
            }
        }
    }

    //为book节点增加一个子节点带有指定命名空间的cover,并设置其属性
    if(!empty($book['cover']['attr']['fileName'])){
        $coverNode = $bookNode->addChild($prefix.'cover',null);
        $coverNode->addAttribute($prefix.'fileName',$book['cover']['attr']['fileName']);
    }

}

//设置header头
header('content-type:text/xml;');
//格式化输出SimpleXML对象
$xmlStr = $rootXML->asXML(); //也可保存到文件 $rootXML->asXML('/path/to/filename.xml');
echo $xmlStr;


读取XML

//给定XML
$xmlStr = <<<XML
<?xml version="1.0" encoding="utf-8"?>
<collection xmlns:lan="language">
    <php:book xmlns:php="php">
        <php:title php:edition="3">PHP Advanced and Object-Oriented Programming: Visual QuickPro Guide</php:title>
        <author:author xmlns:author="LarryUllman">Larry Ullman</author:author>
        <php:year>2012</php:year>
        <php:pages>612</php:pages>
        <php:chapterArr>
          <php:chapter php:number="12">PHP's Command-Line Interface</php:chapter>
          <php:chapter php:number="13">XML and PHP</php:chapter>
          <php:chapter php:number="14">Debugging, Testing, and Performance</php:chapter>
        </php:chapterArr>
        <php:cover php:fileName="phpvqp3.jpg"/>
    </php:book>
    <js:book xmlns:js="javascript">
        <js:title>Modern JavaScript: Develop and Design</js:title>
        <author:author  xmlns:author="LarryUllman">Larry Ullman</author:author>
        <js:year>2012</js:year>
        <js:pages>504</js:pages>
        <js:chapterArr>
          <js:chapter js:number="1" js:pages="24">(Re-)Introducing JavaScript</js:chapter>
          <js:chapter js:number="2" js:pages="32">XML and PHP</js:chapter>
          <js:chapter js:number="3" js:pages="34">Debugging, Testing, and Performance</js:chapter>
        </js:chapterArr>
    </js:book>
</collection>
XML;

$rootXML = simplexml_load_string($xmlStr,null,null,'js',true);////等价于 $rootXML = new SimpleXMLElement($xmlStr,null,false,'js',true);

$data = [];

foreach($rootXML->book as $book){

    $data[$key]['title']   = (string)$book->title; //title值
    $data[$key]['edition'] = (string)$book->title['edition'];//title的edition属性值
    
    //获取book节点下命名空间前缀为author的子节点
    $author = $book->children('author',true);//
    $data[$key]['author'] = (string)$author;//author值
    
    $data[$key]['year'] = (int)$book->year;//year值
    $data[$key]['pages'] = (int)$book->pages;//pages值

    //多种获取属性的方式 开始
    $i = 0;
    foreach($book->chapterArr[0] as $chapter) {
        $data[$key]['chapterArr'][$i]['value'] = (string)$chapter;//chapter值
        //获取chapter节点的number,pages属性
        foreach ($chapter->attributes('js', true) as $chapterKey => $chapterVal) {
            $data[$key]['chapterArr'][$i]['attr'][$chapterKey] = (int)$chapterVal;
        }
        //$data[$key]['chapterArr'][$i]['attr']['number'] = (int)$chapter['number'];//也可这么获取number属性
        //$data[$key]['chapterArr'][$i]['attr']['pages'] = (int)$chapter['pages'];//也可这么获取pages属性
        $i++;
    }

    /*
    //获取chapterArr子节点个数,然后循环获取值及属性
    $chapterNum = $book->chapterArr[0]->count();
    for($i=0;$i<$chapterNum;$i++) {
        $data[$key]['chapterArr'][$i]['value'] = (string)$book->chapterArr->chapter[$i];chapter值
        $data[$key]['chapterArr'][$i]['attr']['number'] = (int)$book->chapterArr->chapter[$i]['number'];number属性
        $data[$key]['chapterArr'][$i]['attr']['pages'] = (int)$book->chapterArr->chapter[$i]['pages'];pages属性
    }
    */
    
    /*
    通过xpath获取属性
    $chapterArr = $bookNode->xpath('//js:book//js:chapterArr//js:chapter');
    $i=0;
    foreach($chapterArr as $k=>$v){
      $data[$key]['chapterArr'][$i]['value'] = (string)$v;
      foreach($attr = $v->attributes('js',true) as $k=>$v){
        $data[$key]['chapterArr'][$i]['attr'][$k] = (int)$v;
      }
      $i++;
    }
    */

    //多种获取属性的方式 结束
    
    //cover值
    $fileName = (string)($book->cover['fileName']) && $data[$key]['cover']['attr']['fileName'] = $fileName;
    
}

var_dump($data);die;

更新XML


//$xmlStr如上
$rootXML = simplexml_load_string($xmlStr,null,null,'js',true);////等价于 $rootXML = new SimpleXMLElement($xmlStr,null,false,'js',true);

//更新标题及chapter的值及属性
$rootXML->book->title = 'modifyXML';
$chapterArrNode = $rootXML->book->chapterArr[0];
$i = 1;
foreach($chapterArrNode as $chapter){
    $chapter[0]           = 'chapter'.$i;//修改值
    $chapter['number'] = 'number'.$i;//修改number属性
    $chapter['pages']  = 'pages'.$i;//修改pages属性
    $i++;
}

//设置header头
header('content-type:text/xml;');
//格式化输出SimpleXML对象
$xmlStr = $rootXML->asXML(); //也可保存到文件 $rootXML->asXML('/path/to/filename.xml');
echo $xmlStr;

删除XML

//$xmlStr如上
$rootXML = simplexml_load_string($xmlStr,null,null,'js',true);////等价于 $rootXML = new SimpleXMLElement($xmlStr,null,false,'js',true);

//删除year
unset($rootXML->book->year);

//删除最后chapter标签
unset($rootXML->book->chapterArr[0]->chapter[2]);

//删除第一个chapter的pages属性
unset($rootXML->book->chapterArr[0]->chapter[0]['pages']);

//使用xpath删除number为2的chapter标签
$rootXML->registerXPathNamespace('js','javascript');
foreach($rootXML->xpath('//js:book//js:chapterArr//js:chapter[@js:number=2]') as $chapter2)
{
    unset($chapter2[0]);
}

//设置header头
header('content-type:text/xml;');
$xmlStr = $rootXML->asXML(); //也可保存到文件 $rootXML->asXML('/path/to/filename.xml');
echo $xmlStr;
php技术微信