PEAR is archived and read-only

This mirror preserves historical PEAR package releases and metadata so existing references remain available.

Home » Configuration » Config » Bug #1877

XML not well formed

Details

Request #1877XML not well formed
Submitted2004-07-14 19:30 UTC
Fromphperror at mail dot linkas dot it
Assignedaashley
StatusClosed
PackageConfig
PHP Version4.3.7
OSLinux
Roadmaps(Not assigned)

Comments

[2004-07-14 19:30 UTC] phperror at mail dot linkas dot it

Description:
------------
If you read an XML file (well formed) with a structure like RSS (which has multiple <item> tags):
1) You will not get the same XML on re-rewriting down it
2) The XML is not well formed

Reproduce code:
---------------
$vecchio_rss = new Config();
$root =& $vecchio_rss->parseConfig('home.xml','xml',array());
$dati=$root->toArray();

$nuovo_rss = new Config();
$nuovi =&$nuovo_rss->parseConfig($dati,"phparray",array());
$erro=$nuovo_rss->writeConfig('home2.xml','xml',array());

Expected result:
----------------
<item>hello</item>
<item>hello2</item>

Actual result:
--------------
<item>
<0>hello</0>
<1>hello2</1>
</item>

which is not well formed and not the same as the one read this because of the transformation into an array.

How to solve:
the writeConfig should 'compress' the structure when writing xml data imported from phparray structure

[2004-08-20 10:47 UTC] bat at flurf dot net

Certainly true. I think an array that has only numeric indices should be converted to something like:

$muppets = array('Kermit','Fozzie','Ralph');

<muppets type="numeric-index-array">
<item index="0">Kermit</item>
<item index="1">Fozzie</item>
<item index="2">Ralph</item>
</muppets>

Note that muppets/@type and item/@index are set to make it easier to read the data back in reliably.

Of course, I'm new to this, having just started looking at PEAR, so I may be wrong about how well this fits in with the existing software.

[2005-01-12 02:25 UTC] scragz at hotmail dot com

Okay, this bug was really messing me up since I need to convert between PHP arrays and XML, so I banged this patch out. I've been up coding for way too long and I'm sure it's totally ridiculous, absolutely the wrong way to go about it, and it probably breaks something else ... but maybe someone can use it as a starting point for a proper patch and it works for my application in any case.

Note that this may wrap when it is output.

$ svn diff XML.php
Index: XML.php
===================================================================
--- XML.php (revision 162)
+++ XML.php (working copy)
@@ -173,6 +173,8 @@
function toString(&$obj)
{
static $deep = -1;
+ static $sectionPath = array();
+ static $sectionOpen = array();
$indent = '';
if (!$obj->isRoot()) {
// no indent for root
@@ -206,12 +208,30 @@
break;
case 'section':
if (!$obj->isRoot()) {
- $string = $indent.'<'.$obj->name;
- $string .= ($this->options['useAttr']) ? XML_Util::attributesToString($obj->attributes) : '';
+ if (!is_int($obj->name)) {
+ $string = $indent.'<'.$obj->name;
+ $string .= ($this->options['useAttr']) ? XML_Util::attributesToString($obj->attributes) : '';
+ } else {
+ $deep--;
+ $indent = str_repeat($this->options['indent'], $deep);
+ if (!$sectionOpen[count($sectionOpen) - 1]) {
+ $sectionOpen[count($sectionOpen) - 1] = true;
+ } else {
+ $currentSection = $sectionPath[count($sectionPath) - 1];
+ if ($currentSection) {
+ $string .= $indent.'</'.$currentSection.'>'.$this->options['linebreak'];
+ $string .= $indent.'<'.$currentSection.'>'.$this->options['linebreak'];
+ }
+ }
+ }
}
if ($children = count($obj->children)) {
if (!$obj->isRoot()) {
- $string .= '>'.$this->options['linebreak'];
+ if (!is_int($obj->name)) {
+ $sectionPath[] = $obj->name;
+ $sectionOpen[] = false;
+ $string .= '>'.$this->options['linebreak'];
+ }
}
for ($i = 0; $i < $children; $i++) {
$string .= $this->toString($obj->getChild($i));
@@ -219,7 +239,13 @@
}
if (!$obj->isRoot()) {
if ($children) {
- $string .= $indent.'</'.$obj->name.'>'.$this->options['linebreak'];
+ if (!is_int($obj->name)) {
+ $string .= $indent.'</'.$obj->name.'>'.$this->options['linebreak'];
+ array_pop($sectionPath);
+ array_pop($sectionOpen);
+ } else {
+ $deep++;
+ }
} else {
$string .= '/>'.$this->options['linebreak'];
}

[2005-04-01 23:34 UTC] ryansking at mac dot com

Ok, forgive me for ignoring this bug for so long, but
I'm kinda confused by it.

Why use Config to read something like RSS? Why not just
XML_Serializer?

[2005-04-10 20:52 UTC] scragz at hotmail dot com

Not RSS, but something _like_ RSS that has multiple sibling tags with the same name. For example, here is part one of my system's main conf files:

<?xml version="1.0" encoding="utf-8"?>
<conf>
<website>
<!-- settings for 1st site -->
</website>
<website>
<!-- settings for 2nd site -->
</website>
<!-- etc. -->
</conf>

Send that to a PHP array and back to XML with Conf, and it ends up like the OP described:

<?xml version="1.0" encoding="utf-8"?>
<conf>
<website>
<0>
<!-- settings for 1st site -->
</0>
<1>
<!-- settings for 2nd site -->
</1>
</website>
</conf>