首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >将XML转换为PHP数组会导致转换后丢失属性数据

将XML转换为PHP数组会导致转换后丢失属性数据
EN

Stack Overflow用户
提问于 2018-04-19 21:26:21
回答 1查看 94关注 0票数 0

我有一个基于此函数的方法:https://github.com/gaarf/XML-string-to-PHP-array/blob/master/xmlstr_to_array.php

现在我修改了它以满足我的需要,现在看起来是这样的:

代码语言:javascript
复制
private function parseXml($xmlString)
{
    $doc = new \DOMDocument;
    $doc->loadXML($xmlString);
    $root = $doc->documentElement;
    $output[$root->tagName] = $this->domnodeToArray($root);

    return $output;
}

/**
 * @param $node
 * @return array|string
 */
private function domNodeToArray($node)
{
    $output = [];
    switch ($node->nodeType)
    {
        case XML_CDATA_SECTION_NODE:
        case XML_TEXT_NODE:
            $output = trim($node->textContent);
            break;
        case XML_ELEMENT_NODE:
            for ($i = 0, $m = $node->childNodes->length; $i < $m; $i++)
            {
                $child = $node->childNodes->item($i);
                $v = $this->domNodeToArray($child);

                if (isset($child->tagName))
                {
                    $t = $child->tagName;

                    if (!isset($output['value'][$t]))
                    {
                        $output['value'][$t] = [];
                    }

                    $output['value'][$t][] = $v;
                }
                else if ($v || $v === '0')
                {
                    $output['value'] = (string)$v;
                }
            }

            if (isset($output['value']) && $node->attributes->length && !is_array($output['value']))
            {
                $output = ['value' => $output['value']];
            }

            if (!$node->attributes->length && isset($output['value']) && !is_array($output['value']))
            {
                $output = ['attributes' => [], 'value' => $output['value']];
            }

            if (isset($output['value']) && is_array($output['value']))
            {
                if ($node->attributes->length)
                {
                    $a = [];
                    foreach ($node->attributes as $attrName => $attrNode)
                    {
                        $a[$attrName] = (string)$attrNode->value;
                    }
                    $output['attributes'] = $a;
                }
                else
                {
                    $output['attributes'] = [];
                }

                foreach ($output['value'] as $t => $v)
                {
                    if (is_array($v) && count($v) == 1 && $t != 'attributes')
                    {
                        $output['value'][$t] = $v[0];
                    }
                }
            }
            break;
    }

    return $output;
}

使用示例XML/XSD字符串,并尝试使用上面的方法(parseXML)将其转换为数组,将导致丢失一些属性,,但只有当使用我的更改版本时,它可以与github存储库中提供的方法一起正常工作。

示例XSD字符串如下所示:

代码语言:javascript
复制
$xsdStr = '<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="book">
        <xs:complexType>

            <xs:sequence>
                <xs:element name="title">
                    <xs:simpleType>
                        <xs:restriction base="xs:string">
                            <xs:maxLength value="40"/>
                        </xs:restriction>
                    </xs:simpleType>
                </xs:element>

                <xs:element name="author">
                    <xs:simpleType>
                        <xs:restriction base="xs:string">
                            <xs:maxLength value="40"/>
                        </xs:restriction>
                    </xs:simpleType>
                </xs:element>

                <xs:element name="character" maxOccurs="unbounded" minOccurs="0">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="name">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:maxLength value="40"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="friend-of" maxOccurs="unbounded" minOccurs="0">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:maxLength value="40"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="since" type="xs:date"/>
                            <xs:element name="qualification" type="xs:string"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
            <xs:attribute name="isbn" use="required"> 
                <xs:simpleType>
                    <xs:restriction base="xs:integer">
                        <xs:totalDigits value="10"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute> 

        </xs:complexType>
    </xs:element>

</xs:schema>';

echo '<pre>';
echo print_r($this->parseXml($xsdStr), true);

此数组的输出将如下所示(print_r):https://pastebin.com/sYvf5Z4X (使用URL,因为它将超过字符限制)。

为了方便起见,maxLength标记在所有出现的标记中都会丢失其值为40的属性value。我只是不明白为什么我的修改后的版本会发生这种情况,而不是原始代码。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-04-19 21:52:04

问题是(必须承认我并不完全理解代码的细节)……

在这里的代码中..。

代码语言:javascript
复制
if (isset($output['value']) && is_array($output['value']))
{
     if ($node->attributes->length)

仅当为节点设置了值时,此操作才有效。我认为发生的情况是任何叶节点都没有值,因此跳过属性值。

代码语言:javascript
复制
if ($node->attributes->length)
{
            // ...
}

if (isset($output['value']) && is_array($output['value']))

如果将属性检查移到此分支之外,则可以正常工作。

不同的是,原始代码不检查是否设置了值,它只检查是否存在某些东西(原始代码的第48行)……

代码语言:javascript
复制
if(is_array($output)) {
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49922294

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档