By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,592 Members | 1,240 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,592 IT Pros & Developers. It's quick & easy.

bizzare array structure from xml_parse_into_struct()

P: n/a
I wanted to test xml_parse_into_struct() so I took the example off of
www.php.net and put this code up on a site:

<?php
$simple = <<<END
<item>
<cbId>345</cbId>
<cbHeadline>Hey there</cbHeadline>
<cbMainContent>God is not dead, he is merely
sleeping.</cbMainContent>
</item>
<item>
<cbId>432</cbId>
<cbHeadline>What a dog, what a dog</cbHeadline>
<cbMainContent>In the manger.</cbMainContent>
</item>
END;

$p = xml_parser_create();
xml_parse_into_struct($p, $simple, $vals, $index);
xml_parser_free($p);
echo "Index array\n";
print_r($index);
echo "\nVals array\n";
print_r($vals);
?>

However, what I got back made no sense to me. Only the first ITEM made
it into the arrays, and all the other tags somehow got counted as
ITEMS. Why?

If I simply want my XML code turned into a two dimensional array, what
is the simplest way to do it? Is xml_parse_into_struct working
correctly, and I simply misunderstand it, or is there another way for
me to do this?

Index array
Array
(
[ITEM] => Array
(
[0] => 0
[1] => 2
[2] => 3
[3] => 5
[4] => 6
[5] => 8
[6] => 9
)

[CBID] => Array
(
[0] => 1
)

[CBHEADLINE] => Array
(
[0] => 4
)

[CBMAINCONTENT] => Array
(
[0] => 7
)

)

Vals array
Array
(
[0] => Array
(
[tag] => ITEM
[type] => open
[level] => 1
[value] =>

)

[1] => Array
(
[tag] => CBID
[type] => complete
[level] => 2
[value] => 345
)

[2] => Array
(
[tag] => ITEM
[value] =>

[type] => cdata
[level] => 1
)

[3] => Array
(
[tag] => ITEM
[value] =>
[type] => cdata
[level] => 1
)

[4] => Array
(
[tag] => CBHEADLINE
[type] => complete
[level] => 2
[value] => Hey there
)

[5] => Array
(
[tag] => ITEM
[value] =>

[type] => cdata
[level] => 1
)

[6] => Array
(
[tag] => ITEM
[value] =>
[type] => cdata
[level] => 1
)

[7] => Array
(
[tag] => CBMAINCONTENT
[type] => complete
[level] => 2
[value] => God is not dead, he is merely sleeping.
)

[8] => Array
(
[tag] => ITEM
[value] =>

[type] => cdata
[level] => 1
)

[9] => Array
(
[tag] => ITEM
[type] => close
[level] => 1
)

)
Jul 17 '05 #1
Share this Question
Share on Google+
15 Replies


P: n/a
lawrence wrote:
$simple = <<<END
<item>
<cbId>345</cbId>
<cbHeadline>Hey there</cbHeadline>
<cbMainContent>God is not dead, he is merely
sleeping.</cbMainContent>
</item>
<item>
<cbId>432</cbId>
<cbHeadline>What a dog, what a dog</cbHeadline>
<cbMainContent>In the manger.</cbMainContent>
</item>
END;


This is not well-formed XML. You need to enclose the item tags inside a root
element; you can only have 1 root element:

<itemlist>
<item>blahblah</item>
<item>blah2blah2</item>
</itemlist>

If you are looking for a simple way to handle XML content without having to
use a DOM parser, have a look at ActiveLink PHP XML Package:

http://www.active-link.com/software/
http://php-xml.sourceforge.net/

Comes with its own parser; read/modify/delete/update XML content with an
easy to use interface; purely written in PHP, does NOT depend on or use any
other XML extension/module. Disclaimer: I am the author of the package.
Jul 17 '05 #2

P: n/a
Zurab Davitiani <ag*@mindless.com> wrote in message news:<xQ*******************@newssvr29.news.prodigy .com>...
This is not well-formed XML. You need to enclose the item tags inside a root
element; you can only have 1 root element:

<itemlist>
<item>blahblah</item>
<item>blah2blah2</item>
</itemlist>


Thanks much. I did as you suggested and wrapped everything above in a
<channel> </channel> tag. Now what I get is workable, though I there
is much about it that I still don't understand. Why does the CHANNEL
array have 4 mentions of CHANNEL, when it only shows up twice, the
opening tag <channgel> and the closing tag </channel>? Why does the
ITEM array have 14 entries, when there are only 4 ITEM tags, two
opening and two closing? Why after cbId is there another ITEM array,
when there is no such tag there, and why is it given the type 'cdata'?

This is the current output:

Index array
Array
(
[CHANNEL] => Array
(
[0] => 0
[1] => 11
[2] => 22
[3] => 23
)

[ITEM] => Array
(
[0] => 1
[1] => 3
[2] => 4
[3] => 6
[4] => 7
[5] => 9
[6] => 10
[7] => 12
[8] => 14
[9] => 15
[10] => 17
[11] => 18
[12] => 20
[13] => 21
)

[CBID] => Array
(
[0] => 2
[1] => 13
)

[CBHEADLINE] => Array
(
[0] => 5
[1] => 16
)

[CBMAINCONTENT] => Array
(
[0] => 8
[1] => 19
)

)

Vals array
Array
(
[0] => Array
(
[tag] => CHANNEL
[type] => open
[level] => 1
[value] =>

)

[1] => Array
(
[tag] => ITEM
[type] => open
[level] => 2
[value] =>

)

[2] => Array
(
[tag] => CBID
[type] => complete
[level] => 3
[value] => 345
)

[3] => Array
(
[tag] => ITEM
[value] =>

[type] => cdata
[level] => 2
)

[4] => Array
(
[tag] => ITEM
[value] =>
[type] => cdata
[level] => 2
)

[5] => Array
(
[tag] => CBHEADLINE
[type] => complete
[level] => 3
[value] => Hey there, handsome
)

[6] => Array
(
[tag] => ITEM
[value] =>

[type] => cdata
[level] => 2
)

[7] => Array
(
[tag] => ITEM
[value] =>
[type] => cdata
[level] => 2
)

[8] => Array
(
[tag] => CBMAINCONTENT
[type] => complete
[level] => 3
[value] => God is not dead, he is merely sleeping.
)

[9] => Array
(
[tag] => ITEM
[value] =>

[type] => cdata
[level] => 2
)

[10] => Array
(
[tag] => ITEM
[type] => close
[level] => 2
)

[11] => Array
(
[tag] => CHANNEL
[value] =>

[type] => cdata
[level] => 1
)

[12] => Array
(
[tag] => ITEM
[type] => open
[level] => 2
[value] =>

)

[13] => Array
(
[tag] => CBID
[type] => complete
[level] => 3
[value] => 432
)

[14] => Array
(
[tag] => ITEM
[value] =>

[type] => cdata
[level] => 2
)

[15] => Array
(
[tag] => ITEM
[value] =>
[type] => cdata
[level] => 2
)

[16] => Array
(
[tag] => CBHEADLINE
[type] => complete
[level] => 3
[value] => What a dog, yes, what a dog
)

[17] => Array
(
[tag] => ITEM
[value] =>

[type] => cdata
[level] => 2
)

[18] => Array
(
[tag] => ITEM
[value] =>
[type] => cdata
[level] => 2
)

[19] => Array
(
[tag] => CBMAINCONTENT
[type] => complete
[level] => 3
[value] => In the manger, was the cow.
)

[20] => Array
(
[tag] => ITEM
[value] =>

[type] => cdata
[level] => 2
)

[21] => Array
(
[tag] => ITEM
[type] => close
[level] => 2
)

[22] => Array
(
[tag] => CHANNEL
[value] =>

[type] => cdata
[level] => 1
)

[23] => Array
(
[tag] => CHANNEL
[type] => close
[level] => 1
)

)
Jul 17 '05 #3

P: n/a
lawrence wrote:
Thanks much. I did as you suggested and wrapped everything above in a
<channel> </channel> tag. Now what I get is workable, though I there
is much about it that I still don't understand. Why does the CHANNEL
array have 4 mentions of CHANNEL, when it only shows up twice, the
opening tag <channgel> and the closing tag </channel>? Why does the
ITEM array have 14 entries, when there are only 4 ITEM tags, two
opening and two closing? Why after cbId is there another ITEM array,
when there is no such tag there, and why is it given the type 'cdata'?


Because this is the way SAX parsers work - they don't parse the document in
its entirety into a single structure (like DOM), they give you bits and
pieces of information and it's up to you to determine how to use them.
Those "type" values are for you to know whether the tag was opened, its
contents parsed, closed, etc. The xml_parse_into_struct tries to give SAX
events a structural image, but I personally don't think it's very efficient
or user-friendly.

If you don't like SAX, or it's not useful for whatever you are doing -
either use a DOM parser or follow the link to the XML package I gave you in
my previous reply.
Jul 17 '05 #4

P: n/a
Zurab Davitiani <ag*@mindless.com> wrote in message news:<avBNc.3314
Because this is the way SAX parsers work - they don't parse the document in
its entirety into a single structure (like DOM), they give you bits and
pieces of information and it's up to you to determine how to use them.
Those "type" values are for you to know whether the tag was opened, its
contents parsed, closed, etc. The xml_parse_into_struct tries to give SAX
events a structural image, but I personally don't think it's very efficient
or user-friendly.

If you don't like SAX, or it's not useful for whatever you are doing -
either use a DOM parser or follow the link to the XML package I gave you in
my previous reply.


That's interesting about SAX parsers. They don't sound very useful.

I'll look into your package, but let me ask a question about it. What
I really want is simply to grab this XML and get back a 2 dimensional
array, then loop through and get out each ITEM, then loop through each
ITEM and the value of each element. Does your package make it easy for
me to grab a 2 dimensional array out of the above 2 dimensional XML?
If not, should I use a DOM parser for that?
Jul 17 '05 #5

P: n/a
Zurab Davitiani <ag*@mindless.com> wrote in message news:<avBNc.3314
Because this is the way SAX parsers work - they don't parse the document in
its entirety into a single structure (like DOM), they give you bits and
pieces of information and it's up to you to determine how to use them.
Those "type" values are for you to know whether the tag was opened, its
contents parsed, closed, etc. The xml_parse_into_struct tries to give SAX
events a structural image, but I personally don't think it's very efficient
or user-friendly.

If you don't like SAX, or it's not useful for whatever you are doing -
either use a DOM parser or follow the link to the XML package I gave you in
my previous reply.


Okay, I went and read the online tutorials for the ActiveLink PHP XML
Package. The organization and cleaness of the documentation is very
impressive. However, my first reaction is that it does way too much
what I need, and would be way too hard to integrate into my existing
code. I've already a lot of code that writes XML, so including this
package would give me a lot of redundant code, I think.

I admire the clean and intelligent simplicity of the ActiveLink site.
Jul 17 '05 #6

P: n/a
lawrence wrote:
That's interesting about SAX parsers. They don't sound very useful.
SAX parsers are good for parsing large XML documents for specific
information. They are quicker and consumer less memory than DOM; but again,
they are not as useful when you want a tree-like structure.
I'll look into your package, but let me ask a question about it. What
I really want is simply to grab this XML and get back a 2 dimensional
array, then loop through and get out each ITEM, then loop through each
ITEM and the value of each element. Does your package make it easy for
me to grab a 2 dimensional array out of the above 2 dimensional XML?
If not, should I use a DOM parser for that?


If you want to create a 2-dimensional array you could, but you would not
need an array at all. If I took your example, it would be:

$myXML = new XML($simple);
$itemsXMLArray = $myXML->getBranches("channel", "item");
foreach($itemsXMLArray as $itemXML) {
print("cbId: " . $itemXML->getTagContent("item/cbId");
//print other fields here
}

Add some error checking and it's good to go.
Jul 17 '05 #7

P: n/a
Zurab Davitiani wrote:
$myXML = new XML($simple);
$itemsXMLArray = $myXML->getBranches("channel", "item");
foreach($itemsXMLArray as $itemXML) {
print("cbId: " . $itemXML->getTagContent("item/cbId");
//print other fields here
}

Add some error checking and it's good to go.


Damn, missing closing parethesis at the end of print line!
Jul 17 '05 #8

P: n/a
Zurab Davitiani <ag*@mindless.com> wrote in message news:<Jc*****************@newssvr21.news.prodigy.c om>...
lawrence wrote:
That's interesting about SAX parsers. They don't sound very useful.


SAX parsers are good for parsing large XML documents for specific
information. They are quicker and consumer less memory than DOM; but again,
they are not as useful when you want a tree-like structure.
I'll look into your package, but let me ask a question about it. What
I really want is simply to grab this XML and get back a 2 dimensional
array, then loop through and get out each ITEM, then loop through each
ITEM and the value of each element. Does your package make it easy for
me to grab a 2 dimensional array out of the above 2 dimensional XML?
If not, should I use a DOM parser for that?


If you want to create a 2-dimensional array you could, but you would not
need an array at all. If I took your example, it would be:

$myXML = new XML($simple);
$itemsXMLArray = $myXML->getBranches("channel", "item");
foreach($itemsXMLArray as $itemXML) {
print("cbId: " . $itemXML->getTagContent("item/cbId");
//print other fields here
}

Add some error checking and it's good to go.


That's very impressive. What is the license on this software? I see on
the website it is described as "free". Does that mean GPL, public
domain, or rights reserved but the cost is $0?
Jul 17 '05 #9

P: n/a
lawrence wrote:
That's very impressive. What is the license on this software? I see on
the website it is described as "free". Does that mean GPL, public
domain, or rights reserved but the cost is $0?


Thanks for the compliment. The license is included with the download archive
- it's LGPL. Remember to read tutorial and documentation (all class methods
are documented), and, if you end up liking it, enjoy!
Jul 17 '05 #10

P: n/a
Could this package be corrupted? I've downloaded the XML package from
this site twice now:

http://www.active-link.com/software/

I keep trying to open it with WinZip, but I always get an error. Is
the double tar normal?

lk******@geocities.com (lawrence) wrote in message news:<da*************************@posting.google.c om>...
Zurab Davitiani <ag*@mindless.com> wrote in message news:<avBNc.3314
Because this is the way SAX parsers work - they don't parse the document in
its entirety into a single structure (like DOM), they give you bits and
pieces of information and it's up to you to determine how to use them.
Those "type" values are for you to know whether the tag was opened, its
contents parsed, closed, etc. The xml_parse_into_struct tries to give SAX
events a structural image, but I personally don't think it's very efficient
or user-friendly.

If you don't like SAX, or it's not useful for whatever you are doing -
either use a DOM parser or follow the link to the XML package I gave you in
my previous reply.


Okay, I went and read the online tutorials for the ActiveLink PHP XML
Package. The organization and cleaness of the documentation is very
impressive. However, my first reaction is that it does way too much
what I need, and would be way too hard to integrate into my existing
code. I've already a lot of code that writes XML, so including this
package would give me a lot of redundant code, I think.

I admire the clean and intelligent simplicity of the ActiveLink site.

Jul 17 '05 #11

P: n/a
.oO(lawrence)
Could this package be corrupted? I've downloaded the XML package from
this site twice now:

http://www.active-link.com/software/
Works here (WinZip 9).
I keep trying to open it with WinZip, but I always get an error. Is
the double tar normal?


It's a gzipped tarball (tar archives, gzip compresses), quite common.
What version of WinZip do you use?

Try this re-packed version (lower compression rate):

<http://www.mfesser.de/temp/ActiveLink-PHP-XML-Package-0.3.4.zip> [58KB]

Micha
Jul 17 '05 #12

P: n/a
Michael Fesser <ne*****@gmx.net> wrote in message
I keep trying to open it with WinZip, but I always get an error. Is
the double tar normal?


It's a gzipped tarball (tar archives, gzip compresses), quite common.
What version of WinZip do you use?

Try this re-packed version (lower compression rate):

<http://www.mfesser.de/temp/ActiveLink-PHP-XML-Package-0.3.4.zip> [58KB]

Micha


Thanks, I've a working version of the package now. I like the fact
that each class is in its own file, that is how my own code works as
well. That makes it somewhat easy to import. It will, I think, only
take a day or two to get the thing working in my own software. They
copyright notice will of course stay where it is in each file. But I
need to have all the files in one directory, so I'm going to have to
completely change the way the files get imported. Thta will take a bit
of reworking. I'm not sure I understand the import() function yet, but
I assume I'll get rid of it, as my own software has its own, very
particular import method.

I may write some additional comments as I study the code. I'll post so
others learning the code can perhaps benefit from whatever I learn.
The code, on brief review, looks like a model of clarity.
Jul 17 '05 #13

P: n/a
From: Zurab Davitiani (ag*@mindless.com)
I'll look into your package, but let me ask a question about it. What
I really want is simply to grab this XML and get back a 2 dimensional
array, then loop through and get out each ITEM, then loop through each
ITEM and the value of each element. Does your package make it easy for
me to grab a 2 dimensional array out of the above 2 dimensional XML?
If not, should I use a DOM parser for that?


If you want to create a 2-dimensional array you could, but you would
not
need an array at all. If I took your example, it would be:

$myXML = new XML($simple);
$itemsXMLArray = $myXML->getBranches("channel", "item");
foreach($itemsXMLArray as $itemXML) {
print("cbId: " . $itemXML->getTagContent("item/cbId");
//print other fields here
}
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>


That is very clean. I'm just getting to use it now. Your package is
one of the few that I did not write that I've been able to use. With
most classes available on the web the programmer makes too many
assumptions and the code doesn't port well.
Jul 17 '05 #14

P: n/a
If I have an RSS newsfeed like this:

<?xml version="1.0" encoding="utf-8"?><!-- generator="whocares" -->
<rss version="0.92">
<channel>
<title>Website Name</title>
<link>http://www.websiteurl.com</link>
<description>Description of website</description>
<lastbuilddate>Sun, 19 Sep 2004 04:34:52 +0000</lastbuilddate>
<docs>http://backend.userland.com/rss092</docs>

<item>
<title>1st Title</title>
<description>1st Description</description>
<link>http://www.websiteurl.com/1stlink/</link>
</item>

<item>
<title>2nd Title</title>
<description>2nd Description</description>
<link>http://www.websiteurl.com/2ndlink/</link>
</item>
</channel>
</rss>

And the following code is used to parse that file/feed:

<?php
$feed = 'http://www.example.com/feed/rss/';

/* ...create and XML parser... */
$xml_parser = xml_parser_create();

/* ...open the feed and parse it... */
$fp = @fopen($feed, 'rb');
if (is_resource($fp)) {
xml_parse_into_struct( $xml_parser, $fp, $vals, $index );
}
@fclose($fp);

/* ...free parser */
xml_parser_free( $xml_parser );
?>

How do I extract the values from $xml_parser?
Jul 17 '05 #15

P: n/a
Argh! I thought I was making a new post. Disregard.

--
--
Remove the period between my first and last name if you wish to e-mail me
directly
"Charles Stricklin" <ch**************@bellsouth.net> wrote in message
news:C8********************@bignews6.bellsouth.net ...
If I have an RSS newsfeed like this:

<?xml version="1.0" encoding="utf-8"?><!-- generator="whocares" -->
<rss version="0.92">
<channel>
<title>Website Name</title>
<link>http://www.websiteurl.com</link>
<description>Description of website</description>
<lastbuilddate>Sun, 19 Sep 2004 04:34:52 +0000</lastbuilddate>
<docs>http://backend.userland.com/rss092</docs>

<item>
<title>1st Title</title>
<description>1st Description</description>
<link>http://www.websiteurl.com/1stlink/</link>
</item>

<item>
<title>2nd Title</title>
<description>2nd Description</description>
<link>http://www.websiteurl.com/2ndlink/</link>
</item>
</channel>
</rss>

And the following code is used to parse that file/feed:

<?php
$feed = 'http://www.example.com/feed/rss/';

/* ...create and XML parser... */
$xml_parser = xml_parser_create();

/* ...open the feed and parse it... */
$fp = @fopen($feed, 'rb');
if (is_resource($fp)) {
xml_parse_into_struct( $xml_parser, $fp, $vals, $index );
}
@fclose($fp);

/* ...free parser */
xml_parser_free( $xml_parser );
?>

How do I extract the values from $xml_parser?

Jul 17 '05 #16

This discussion thread is closed

Replies have been disabled for this discussion.