在 CakePHP 中,我知道 cake.libs 中的 XML 类。我喜欢这个易于使用的类,因为您可以将数组转换为带有属性的 xml。
在当前的项目中,我正在使用 Zend Framework,但我错过了这个不错的课程。
有人知道如何轻松地将 PHP 数组转换为带有属性的 XML 吗?
我尝试了这个,但不幸的是,处理数据库中的结果数组并不容易,因为你必须定义数组内的属性。
也许我错过了采埃孚的一些东西?或者有人知道如何将 CakePHP 类适配到 ZF 吗?
非常感谢您提供任何有用的提示。
此函数将允许您使用简单的 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());
您可以在此 URL 获得一些答案如何将数组转换为 SimpleXML
另一种/快速且简单的方法是将数组数据转换为 JSON,使用 Zend 库也会更快。使用以下函数将数组转换为 JSON 非常简单。
Zend_Json::encode() and Zend_Json_Encoder::encode()
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>
我尝试了 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>