# PHP中XML处理

* DOM ：一次性将xml载入内存，内存问题需要注意
* SimpleXML：小文件可以选择它，不支持命令空间
* XMLReader  :  边读边操作, “拉取”模型,大文件操作
* XML Parser  :  SAX模型是一个“推送”模型,大文件操作

## SimpleXML

**语法**

PHP的语法simplexml\_load\_string（）函数具有以下语法。

```php
simplexml_load_string(data,classname,options,ns,is_prefix);
```

**参数**

| 参数         | 是必须的 | 描述                                                          |
| ---------- | ---- | ----------------------------------------------------------- |
| 数据         | 需要。  | 一个格式正确的XML字符串                                               |
| 班级名称       | 可选的。 | 新对象的类                                                       |
| 选项         | 可选的。 | 额外的Libxml参数。通过指定选项和1或0（TRUE或FALSE，例如LIBXML\_NOBLANKS（1））来设置 |
| ns         | 可选的。 | 命名空间前缀或URI                                                  |
| is\_prefix | 可选的。 | 如果ns是前缀，则为TRUE。如果ns是URI，则为FALSE。默认值为FALSE                   |

**选项的可能值：**

LIBXML\_COMPACT - 激活节点分配优化（可加速应用程序）

* LIBXML\_DTDATTR - 设置默认DTD属性
* LIBXML\_DTDLOAD - 加载外部子集
* LIBXML\_DTDVALID - 使用DTD进行验证
* LIBXML\_NOBLANKS - 删除空白节点
* LIBXML\_NOCDATA - 将CDATA合并为文本节点
* LIBXML\_NOEMPTYTAG - 展开空标记（例如对\<br> \</ br>），仅在DOMDocument-> save（）和DOMDocument-> saveXML（）函数中可用
* LIBXML\_NOENT - 替代实体
* LIBXML\_NOERROR - 不显示错误报告
* LIBXML\_NONET - 加载文档时禁用网络访问
* LIBXML\_NOWARNING - 不显示警告报告
* LIBXML\_NOXMLDECL - 保存文档时删除XML声明
* LIBXML\_NSCLEAN - 删除多余的命名空间声明
* LIBXML\_PARSEHUGE - 设置XML\_PARSE\_HUGE标志，放宽解析器的任何硬编码限制。这会影响极限，如文档的最大深度和文本节点大小的限制
* LIBXML\_XINCLUDE - 实现XInclude替换
* LIBXML\_ERR\_ERROR - 获取可恢复的错误
* LIBXML\_ERR\_FATAL - 获取致命错误
* LIBXML\_ERR\_NONE - 获取无错误
* LIBXML\_ERR\_WARNING - 获取简单的警告
* LIBXML\_VERSION - 获取libxml版本
* LIBXML\_DOTTED\_VERSION - 获取点分的libxml版本

**返回值**

成功时返回SimpleXMLElement对象。失败时为FALSE。

**示例**

简单示例

```php
$string = <<<XML
<?xml version='1.0'?>
<document>
  <cmd>login</cmd>
  <login>imdonkey</login>
</document>
XML;

$xml = simplexml_load_string($string);
print_r($xml);
```

结果:

```
SimpleXMLElement Object ( [cmd] => login [login] => imdonkey )
```

文件不大时,可以配合以下方式转为数组使用

```php
$string = <<<XML
<?xml version='1.0'?>
<document>
<cmd>login</cmd>
<login>imdonkey</login>
</document>
XML;

$xml = simplexml_load_string($string);
$arr = toArray($xml);
print_r($arr);
echo $arr['cmd'];

function toArray($object)
{
    $object = json_decode(json_encode($object), true);
    return $object;
}
```

### 常见CDATA 包裹数据处理

```php
simplexml_load_string($string, null, LIBXML_NOCDATA);
```

示例:

```php
$string = <<<XML
<?xml version='1.0'?>
<document>
<cmd><![CDATA[login]]></cmd>
<login><![CDATA[imdonkey]]></login>
</document>
XML;

$xml = simplexml_load_string($string, null, LIBXML_NOCDATA);
var_dump($xml);
```

资料:

[微信开发基础之php函数simplexml\_load\_string](http://www.phpos.net/jichu/132.html)

## XMLReader

```
<?xml version="1.0" encoding="utf-8"?>
<collection>
 <cd>
  <title type="hk">港台明星</title>
  <artist>刘德华</artist>
  <year>1995</year>
 </cd>
 <cd>
  <title>大陆演员</title>
  <artist>范冰冰</artist>
  <year>1997</year>
 </cd>
</collection><?xml version="1.0" encoding="utf-8"?>
<collection>
 <cd>
  <title type="hk">港台明星</title>
  <artist>刘德华</artist>
  <year>1995</year>
 </cd>
 <cd>
  <title>大陆演员</title>
  <artist>范冰冰</artist>
  <year>1997</year>
 </cd>
</collection>
```

示例

```php
<?php
$items=array();
$reader=new XMLReader();
$reader->open('collection.xml', 'utf-8');
while ($reader->read()){
  //get current data
  if($reader->name=="cd" && $reader->nodeType==XMLReader::ELEMENT){
    $item=[];
    while($reader->read() && $reader->name !="cd" ){
        if($reader->nodeType!=XMLReader::ELEMENT)continue;
        $name=$reader->name;
        $value=$reader->readString();
        $item[$name]=$value;
    }
     $items[]=$item;
  }
}
$reader->close();

print_r($items);
```

## XML Parser

```php
<?php

$file = "collection.xml";
$depth = array();

function startElement($parser, $name, $attrs) 
{
    global $depth;
     /*
    for ($i = 0; $i < $depth[$parser]; $i++) {
        echo "  ";
    }*/
    //echo "$name\n";
    print_r($attrs);
    //$depth[$parser]++;
}

function endElement($parser, $name) 
{
    global $depth;
    //$depth[$parser]--;
}

function data($parser, $data) {
    var_dump($data);
}

$xml_parser = xml_parser_create('UTF-8');
xml_parser_set_option ( $xml_parser , XML_OPTION_SKIP_WHITE  , 1 ) ;
xml_parser_set_option ( $xml_parser , XML_OPTION_CASE_FOLDING  , 0 ) ;

xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "data");

$fp = fopen($file, "r");


while ($data = fread($fp, 4096)) {
    if (!xml_parse($xml_parser, $data, feof($fp))) {
        die(sprintf("XML error: %s at line %d",
                    xml_error_string(xml_get_error_code($xml_parser)),
                    xml_get_current_line_number($xml_parser)));
    }
}
xml_parser_free($xml_parser);
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://phper.shujuwajue.com/phpwen-jian-bian-cheng/phpzhong-xml-chu-li.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
