PHP 数组到带有属性的 XML

问题描述 投票:0回答:4

在 CakePHP 中,我知道 cake.libs 中的 XML 类。我喜欢这个易于使用的类,因为您可以将数组转换为带有属性的 xml。
在当前的项目中,我正在使用 Zend Framework,但我错过了这个不错的课程。

有人知道如何轻松地将 PHP 数组转换为带有属性的 XML 吗?

我尝试了这个,但不幸的是,处理数据库中的结果数组并不容易,因为你必须定义数组内的属性。

也许我错过了采埃孚的一些东西?或者有人知道如何将 CakePHP 类适配到 ZF 吗?

非常感谢您提供任何有用的提示。

php arrays zend-framework cakephp
4个回答
2
投票

此函数将允许您使用简单的 PHP 数组变量创建 XML 文档。节点只是相互堆叠,并将其命名为“Attribute_XXX”会将属性 XXX 添加到该父节点。

function to_xml(SimpleXMLElement $object, array $data)
{
    $attr = "Attribute_";
    foreach ($data as $key => $value) {
        if (is_array($value)) {
            $new_object = $object->addChild($key);
            to_xml($new_object, $value);
        } else {
            if(strpos($key, $attr) !== false){
                $object->addAttribute(substr($key, strlen($attr)), $value);
            }else{
                $object->addChild($key, $value);
            }
        }
    }
}

用途:

$my_array = array (
    'TagN1' => array (
        'TagInsideOfIt' => array (
            'Atrribute_IDuser' => 'anything',
            'RegularTag' => 'whatever',
            'Address' => array(
                'Attribute_ID' => '111',
                'Attribute_key' => 'aaa',
                'Company' => 'Google Inc.'
            )
        )
    )
);

$xml = new SimpleXMLElement('<root/>');

to_xml($xml, $my_array);

Header('Content-type: text/xml');
print($xml->asXML());

0
投票

您可以在此 URL 获得一些答案如何将数组转换为 SimpleXML

另一种/快速且简单的方法是将数组数据转换为 JSON,使用 Zend 库也会更快。使用以下函数将数组转换为 JSON 非常简单。

Zend_Json::encode() and Zend_Json_Encoder::encode()

0
投票

Tanks,使用@jezda159的代码,我为我修改了,这是我的代码:

数组:

   $elements_array = array(
            "node" => array(
                "subnode" => array(
                    "[attribute]" => "valueOfAttribute",
                    "[second-attribute]" => "valueOfAttribute",
                    "second-subnode" => array(
                        "[attribute]" => "valueOfAttribute",
                        "[second-attribute]" => "valueOfAttribute",
                    ),
                    "ListOfElements" => array(
                        "one",
                        "two",
                        "tree"
                    )
                )
            ),
        );

代码:

    function array_to_xml($data, $object){
        foreach ($data as $key => $value) {
            $keyname = is_numeric( $key ) ? "item".$key : $key;
            if (is_array($value)) {
                $new_object = $object->addChild($keyname);
                array_to_xml($value, $new_object);
            } else {
                preg_match("#\[([a-z0-9-_]+)\]#i", $keyname, $attr);
                if( count($attr) ){
                    $object->addAttribute($attr[1], $value);
                }else{
                    $object->addChild($keyname, $value);
                }
            }
        }
    }
$xml_user_info = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8" ?><Elements></Elements>');

//function call to convert array to xml
array_to_xml($elements_array,$xml_user_info);
header('Content-type: text/xml');
//show generated xml file
echo $xml_user_info->asXML();

结果:

<?xml version="1.0" encoding="UTF-8"?>
<Elements>
<node>
<subnode attribute="valueOfAttribute" second-attribute="valueOfAttribute">
<second-subnode attribute="valueOfAttribute" second-attribute="valueOfAttribute"/>
<ListOfElements>
<item0>one</item0>
<item1>two</item1>
<item2>tree</item2>
</ListOfElements>
</subnode>
</node>
</Elements>

0
投票

我尝试了 stackoverflow 中的几个答案,但它们都存在重复标签的问题,这些标签在一个数组中无法轻松完成,并且具有属性,因此我修改了从 PHP - XMLWriter 将嵌套数组写入文件

获得的一个类

我做了一个小技巧,在键或数组中添加一些特殊字符。 ### 对于嵌套元素,我需要放置相同的标签,对于属性,我需要放置 @@@。检查下面的 XML 示例。

这是课程:

<?php

/* Key of the arrays will be the tags of the XML
    It's allowed to place on the keys of the arrays structure like this:
        'foo attribute1=value1 attribute2=value2' => 'bar'

    And it will create the attributes for that tag
*/
class XmlConstruct extends XMLWriter
{

    /**
     * Constructor.
     * @param string $prm_rootElementName A root element's name of a current xml document
     * @param string $prm_xsltFilePath Path of a XSLT file.
     * @access public
     * @param null
     */
    public function __construct($prm_rootElementName, $prm_xsltFilePath = '')
    {
        $this->openMemory();
        $this->setIndent(true);
        $this->setIndentString("\t");
        $this->startDocument('1.0', 'UTF-8');

        if ($prm_xsltFilePath) {
            $this->writePi('xml-stylesheet', 'type="text/xsl" href="' . $prm_xsltFilePath . '"');
        }

        $this->startElementWithAttrs( $prm_rootElementName );       
    }

    /**
     * Creates a XML element taking care if tye key of the array has attributes we should add to the XML
     * @access private
     * @param string $prm_elementName An element's name, which can contain attributes
     * @return null
     */
    function startElementWithAttrs( $prm_elementName )
    {
        // Checking if key of array has attributes
        $attrArray = explode('@@@', $prm_elementName);
        $tag = array_shift($attrArray);

        // Only numbers tags in XML are not allowed
        if ( is_numeric($tag) ) {
            $tag = 'num' . $tag;
        }

        if ( $pos = strpos($tag, '###') ) {
            // If tag has ### means we need to repeat that tag on the XML. Removing ### till the end.
            $tag = substr($tag, 0, $pos);
        }

        $this->startElement($tag);

        foreach ( $attrArray as $attr) {
            list($attr_name, $attr_value) = explode( '=', trim($attr) );
            $this->writeAttribute( $attr_name, $attr_value );
        }
    }

    /**
     * Set an element with a text to a current xml document.
     * @access public
     * @param string $prm_elementName An element's name
     * @param string $prm_ElementText An element's text
     * @return null
     */
    public function setElement($prm_elementName, $prm_ElementText)
    {
        $this->startElementWithAttrs($prm_elementName);
        $this->text($prm_ElementText);
        $this->endElement();
    }

    /**
     * Construct elements and texts from an array.
     * The array should contain an attribute's name in index part
     * and a attribute's text in value part.
     * @access public
     * @param array $prm_array Contains attributes and texts
     * @return null
     */
    public function fromArray($prm_array)
    {
        if ( is_array($prm_array) ) {
            foreach ($prm_array as $index=>$element) {
                if ( is_array($element) ) {
                    $this->startElementWithAttrs($index);
                    $this->fromArray($element);
                    $this->endElement();
                } else {
                    $this->setElement($index, $element);
                }
            }
        }
    }

    /**
     * Return the content of a current xml document.
     * @access public
     * @param null
     * @return string Xml document
     */

    public function getDocument()
    {
        $this->endElement();
        $this->endDocument();
        return $this->outputMemory();
    }

    /**
     * Output the content of a current xml document.
     * @access public
     * @param null
     */

    public function output()
    {
        header('Content-type: text/xml');
        echo $this->getDocument();
    }
}

这是一个完整的示例:

$arr['catalog@@@name=Catalog Name@@@tag=One tag'] = array(
    'cd###1'=>array(
        'title'=>'Empire Burlesque',
        'ARTIST'=>'Bob Dylan',
        'COUNTRY'=>'USA',
        'COMPANY'=>'Columbia',
        'PRICE'=>'10.90',
        'YEAR'=>'1985'
    ),
    'cd###2'=>array(
        'title'=>'Hide your heart',
        'ARTIST'=>'Bonnie Tyler',
        'COUNTRY'=>'USA',
        'COMPANY'=>'CBS Records',
        'PRICE'=>'9.90',
        'YEAR'=>'1988'
    ),
    'cd###3@@@active=yes'=>array(
        'title'=>'Greatest Hits',
        'ARTIST'=>'Dolly Parton',
        'COUNTRY'=>'USA',
        'COMPANY'=>'RCA',
        'PRICE'=>'9.90',
        'YEAR'=>'1982'
    ),
    'cd###4'=>array(
        'title'=>'Still got the blues',
        'ARTIST'=>'Gary Moore',
        'COUNTRY'=>'UK',
        'COMPANY'=>'Virgin records',
        'PRICE'=>'10.20',
        'YEAR'=>'1990'
    ),
    'lastUpdate'=>'2024-01-01 12:30'
);


$XmlConstruct = new XmlConstruct('root');
$XmlConstruct->fromArray($arr);
echo $XmlConstruct->getDocument();

这就是结果:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <catalog name="Catalog Name" tag="One tag">
        <cd>
            <title>Empire Burlesque</title>
            <ARTIST>Bob Dylan</ARTIST>
            <COUNTRY>USA</COUNTRY>
            <COMPANY>Columbia</COMPANY>
            <PRICE>10.90</PRICE>
            <YEAR>1985</YEAR>
        </cd>
        <cd>
            <title>Hide your heart</title>
            <ARTIST>Bonnie Tyler</ARTIST>
            <COUNTRY>USA</COUNTRY>
            <COMPANY>CBS Records</COMPANY>
            <PRICE>9.90</PRICE>
            <YEAR>1988</YEAR>
        </cd>
        <cd active="yes">
            <title>Greatest Hits</title>
            <ARTIST>Dolly Parton</ARTIST>
            <COUNTRY>USA</COUNTRY>
            <COMPANY>RCA</COMPANY>
            <PRICE>9.90</PRICE>
            <YEAR>1982</YEAR>
        </cd>
        <cd>
            <title>Still got the blues</title>
            <ARTIST>Gary Moore</ARTIST>
            <COUNTRY>UK</COUNTRY>
            <COMPANY>Virgin records</COMPANY>
            <PRICE>10.20</PRICE>
            <YEAR>1990</YEAR>
        </cd>
        <lastUpdate>2024-01-01 12:30</lastUpdate>
    </catalog>
</root>
© www.soinside.com 2019 - 2024. All rights reserved.