首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

用 PHP 将 XML 转换成 JSON(2)

用 PHP 将 XML 转换成 JSON(2)

理解 PHP 代码这个 xml2json 实现包括三部分:
  • xml2json.php —— 这个 PHP 类包括两个静态函数
  • xml2json_test.php —— 执行xml2json 转换函数的测试驱动程序
  • test1.xml、test2.xml、test3.xml、test4.xml —— 复杂程度不同的 XML 文件
为了简化起见,本文省略了代码中的详细注释。不过后面附的源文件中包含完整的注释。要了解完全的程序逻辑细节,请参阅所附的源文件(请参阅)。
定义了一些要用到的常量。第一行代码导入了 Services_JSON 实现。
清单 4. 定义 xml2json.php 中的常量
1
2
3
4
5
6
7
8
9
10
11
require_once 'json/JSON.php';
// Internal program-specific Debug option.
define ("DEBUG", false);
// Maximum Recursion Depth that we can allow.
define ("MAX_RECURSION_DEPTH_ALLOWED", 25);
// An empty string
define ("EMPTY_STR", "");
// SimpleXMLElement object property name for attributes
define ("SIMPLE_XML_ELEMENT_OBJECT_PROPERTY_FOR_ATTRIBUTES", "@attributes");
// SimpleXMLElement object name.
define ("SIMPLE_XML_ELEMENT_PHP_CLASS", "SimpleXMLElement");




中的代码片段是 xml2json 转换器的入口函数。它接收 XML 数据作为输入,将 XML 字符串转化成 SimpleXMLElement 对象,然后发送给该类的另一个(递归)函数作为输入。这个函数将 XML 元素转化成 PHP 关联数组。这个数组再被传给 Services_JSON 编码器作为其输入,该编码器给出 JSON 格式的输出。
清单 5. 使用 xml2json.php 中的 Services_JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static function transformXmlStringToJson($xmlStringContents) {
$simpleXmlElementObject = simplexml_load_string($xmlStringContents);
<br>
    if ($simpleXmlElementObject == null) {
return(EMPTY_STR);
}
<br>
    $jsonOutput = EMPTY_STR;
<br>
    // Let us convert the XML structure into PHP array structure.
$array1 = xml2json::convertSimpleXmlElementObjectIntoArray($simpleXmlElementObject);
<br>
    if (($array1 != null) && (sizeof($array1) > 0)) {
// Create a new instance of Services_JSON
$json = new Services_JSON();
// Let us now convert it to JSON formatted data.
$jsonOutput = $json->encode($array1);
} // End of if (($array1 != null) && (sizeof($array1) > 0))
<br>
    return($jsonOutput);
} // End of function transformXmlStringToJson




中这段长长的代码片段采用了 PHP 开放源码社区(请参阅)提出的递归技术。它接收输入的 SimpleXMLElement 对象,沿着嵌套的 XML 树递归遍历。将访问过的 XML 元素保存在 PHP 关联数组中。可以通过修改 中定义的常量来改变最大递归深度。
    清单 6. xml2json.php 中的转换逻辑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
public static function convertSimpleXmlElementObjectIntoArray($simpleXmlElementObject,
&$recursionDepth=0) {
// Keep an eye on how deeply we are involved in recursion.
<br>
    if ($recursionDepth > MAX_RECURSION_DEPTH_ALLOWED) {
// Fatal error. Exit now.
return(null);
}
<br>
    if ($recursionDepth == 0) {
if (get_class($simpleXmlElementObject) != SIMPLE_XML_ELEMENT_PHP_CLASS) {
// If the external caller doesn't call this function initially
// with a SimpleXMLElement object, return now.
return(null);
} else {
// Store the original SimpleXmlElementObject sent by the caller.
// We will need it at the very end when we return from here for good.
$callerProvidedSimpleXmlElementObject = $simpleXmlElementObject;
}
} // End of if ($recursionDepth == 0) {
<br>
    if (get_class($simpleXmlElementObject) == SIMPLE_XML_ELEMENT_PHP_CLASS) {
        // Get a copy of the simpleXmlElementObject
        $copyOfsimpleXmlElementObject = $simpleXmlElementObject;
        // Get the object variables in the SimpleXmlElement object for us to iterate.
        $simpleXmlElementObject = get_object_vars($simpleXmlElementObject);
    }
<br>
    // It needs to be an array of object variables.
    if (is_array($simpleXmlElementObject)) {
        // Is the array size 0? Then, we reached the rare CDATA text if any.
        if (count($simpleXmlElementObject) <= 0) {
            // Let us return the lonely CDATA. It could even be
            // an empty element or just filled with whitespaces.
            return (trim(strval($copyOfsimpleXmlElementObject)));
        }
<br>
        // Let us walk through the child elements now.
        foreach($simpleXmlElementObject as $key=>$value) {
            // When this block of code is commented, XML attributes will be
            // added to the result array.
            // Uncomment the following block of code if XML attributes are
            // NOT required to be returned as part of the result array.
            /*
            if($key == SIMPLE_XML_ELEMENT_OBJECT_PROPERTY_FOR_ATTRIBUTES) {
                continue;
            }
            */
<br>
            // Let us recursively process the current element we just visited.
            // Increase the recursion depth by one.
            $recursionDepth++;
            $resultArray[$key] =
                xml2json::convertSimpleXmlElementObjectIntoArray($value, $recursionDepth);
<br>
            // Decrease the recursion depth by one.
            $recursionDepth--;
        } // End of foreach($simpleXmlElementObject as $key=>$value) {
<br>
        if ($recursionDepth == 0) {
            // That is it. We are heading to the exit now.
            // Set the XML root element name as the root [top-level] key of
            // the associative array that we are going to return to the caller of this
            // recursive function.
            $tempArray = $resultArray;
            $resultArray = array();
            $resultArray[$callerProvidedSimpleXmlElementObject->getName()] = $tempArray;
        }
<br>
        return ($resultArray);
    } else {
        // We are now looking at either the XML attribute text or
        // the text between the XML tags.
        return (trim(strval($simpleXmlElementObject)));
    } // End of else
} // End of function convertSimpleXmlElementObjectIntoArray.




成功遍历 XML 树之后,该函数就用 PHP 关联数组转换和存储了所有的 XML 元素(根元素和所有的孩子元素)。复杂的 XML 文档,得到的 PHP 数组也同样复杂。一旦 PHP 数组构造完成,Services_JSON 编码器就很容易将其转化成 JSON 格式的数据了。要了解其中的递归逻辑,请参阅存档的源文件。
返回列表