Jump to content

XML File with tags


Go to solution Solved by Barand,

Recommended Posts

Hello all,

I hope everyone is well. Thanks in advance for any assistance you can give me on this. I've got an XML file of the KJV Bible. I can parse it using SimpleXML and have working code. My challenge is this. Inside the XML file, certain verses (A TON) have HTML code in the body of the verses. See below for XML snippet & output snippet. 

Snippet from XML File (notice the <i> tags & <span class="j"> elements within the verses)

<chapter num="17">
    <verse num="1">And after six days Jesus taketh Peter, James, and John his brother, and bringeth them up into an high mountain apart,</verse>
    <verse num="2">And was transfigured before them: and his face did shine as the sun, and his raiment was white as the light.</verse>
    <verse num="3">And, behold, there appeared unto them Moses and Elias talking with him.</verse>
    <verse num="4">Then answered Peter, and said unto Jesus, Lord, it is good for us to be here: if thou wilt, let us make here three tabernacles; one for thee, and one for Moses, and one for Elias.</verse>
    <verse num="5">While he yet spake, behold, a bright cloud overshadowed them: and behold a voice out of the cloud, which said, This is my beloved Son, in whom I am well pleased; hear ye him.</verse>
    <verse num="6">And when the disciples heard <i>it,</i> they fell on their face, and were sore afraid.</verse>
    <verse num="7">And Jesus came and touched them, and said, <span class="j">Arise, and be not afraid. </span></verse>
    <verse num="8">And when they had lifted up their eyes, they saw no man, save Jesus only.</verse>
    <verse num="9">And as they came down from the mountain, Jesus charged them, saying, <span class="j">Tell the vision to no man, until the Son of man be risen again from the dead. </span></verse>
    <verse num="10">And his disciples asked him, saying, Why then say the scribes that Elias must first come?</verse>
    <verse num="11">And Jesus answered and said unto them, <span class="j">Elias truly shall first come, and restore all things. </span></verse>
    <verse num="12"><span class="j">But I say unto you, That Elias is come already, and they knew him not, but have done unto him whatsoever they listed. Likewise shall also the Son of man suffer of them. </span></verse>
    <verse num="13">Then the disciples understood that he spake unto them of John the Baptist.</verse>
    <verse num="14">And when they were come to the multitude, there came to him a <i>certain</i> man, kneeling down to him, and saying,</verse>
    <verse num="15">Lord, have mercy on my son: for he is lunatick, and sore vexed: for ofttimes he falleth into the fire, and oft into the water.</verse>
    <verse num="16">And I brought him to thy disciples, and they could not cure him.</verse>
    <verse num="17">Then Jesus answered and said, <span class="j">O faithless and perverse generation, how long shall I be with you? how long shall I suffer you? bring him hither to me. </span></verse>

As you might have guessed, <span class="j"> & <i> turn into attributes or disappear within Simple XML and they break badly leaving parts of the verses missing or broken altogether. Is there a way to prevent this & get the code raw between the verse tags? I'm aware of CData, but this file is 33000 lines and manually is out the door & I'm not sure if regex would work or not. Any advice?

Here is the output for the above section...  Code used is <?php echo '<pre>';  print_r( simplexml_load_file( $fileName ) ); ?>. I added a few comments to draw attention to what is missing.

[verse] => Array
(
	[0] => And after six days Jesus taketh Peter, James, and John his brother, and bringeth them up into an high mountain apart,
	[1] => And was transfigured before them: and his face did shine as the sun, and his raiment was white as the light.
	[2] => And, behold, there appeared unto them Moses and Elias talking with him.
	[3] => Then answered Peter, and said unto Jesus, Lord, it is good for us to be here: if thou wilt, let us make here three tabernacles; one for thee, and one for Moses, and one for Elias.
	[4] => While he yet spake, behold, a bright cloud overshadowed them: and behold a voice out of the cloud, which said, This is my beloved Son, in whom I am well pleased; hear ye him.
	[5] => And when the disciples heard  they fell on their face, and were sore afraid.                              // missing it after heard
	[6] => And Jesus came and touched them, and said,                                                                // Missing a chunk here
	[7] => And when they had lifted up their eyes, they saw no man, save Jesus only.
	[8] => And as they came down from the mountain, Jesus charged them, saying,                                      // missing a chunk here
	[9] => And his disciples asked him, saying, Why then say the scribes that Elias must first come?
	[10] => And Jesus answered and said unto them, 
	[11] => SimpleXMLElement Object                                                                             // the whole thing line became an att
		(
			[@attributes] => Array
				(
					[num] => 12
				)

			[span] => But I say unto you, That Elias is come already, and they knew him not, but have done unto him whatsoever they listed. Likewise shall also the Son of man suffer of them. 
		)

	[12] => Then the disciples understood that he spake unto them of John the Baptist.
	[13] => And when they were come to the multitude, there came to him a  man, kneeling down to him, and saying,
	[14] => Lord, have mercy on my son: for he is lunatick, and sore vexed: for ofttimes he falleth into the fire, and oft into the water.
	[15] => And I brought him to thy disciples, and they could not cure him.
	[16] => Then Jesus answered and said, 

Thanks for any help you can offer.

Link to comment
Share on other sites

  • Solution

Have you triedd using xpath()?

<?php
$str = '<xml><chapter num="17">
    <verse num="1">And after six days Jesus taketh Peter, James, and John his brother, and bringeth them up into an high mountain apart,</verse>
    <verse num="2">And was transfigured before them: and his face did shine as the sun, and his raiment was white as the light.</verse>
    <verse num="3">And, behold, there appeared unto them Moses and Elias talking with him.</verse>
    <verse num="4">Then answered Peter, and said unto Jesus, Lord, it is good for us to be here: if thou wilt, let us make here three tabernacles; one for thee, and one for Moses, and one for Elias.</verse>
    <verse num="5">While he yet spake, behold, a bright cloud overshadowed them: and behold a voice out of the cloud, which said, This is my beloved Son, in whom I am well pleased; hear ye him.</verse>
    <verse num="6">And when the disciples heard <i>it,</i> they fell on their face, and were sore afraid.</verse>
    <verse num="7">And Jesus came and touched them, and said, <span class="j">Arise, and be not afraid. </span></verse>
    <verse num="8">And when they had lifted up their eyes, they saw no man, save Jesus only.</verse>
    <verse num="9">And as they came down from the mountain, Jesus charged them, saying, <span class="j">Tell the vision to no man, until the Son of man be risen again from the dead. </span></verse>
    <verse num="10">And his disciples asked him, saying, Why then say the scribes that Elias must first come?</verse>
    <verse num="11">And Jesus answered and said unto them, <span class="j">Elias truly shall first come, and restore all things. </span></verse>
    <verse num="12"><span class="j">But I say unto you, That Elias is come already, and they knew him not, but have done unto him whatsoever they listed. Likewise shall also the Son of man suffer of them. </span></verse>
    <verse num="13">Then the disciples understood that he spake unto them of John the Baptist.</verse>
    <verse num="14">And when they were come to the multitude, there came to him a <i>certain</i> man, kneeling down to him, and saying,</verse>
    <verse num="15">Lord, have mercy on my son: for he is lunatick, and sore vexed: for ofttimes he falleth into the fire, and oft into the water.</verse>
    <verse num="16">And I brought him to thy disciples, and they could not cure him.</verse>
    <verse num="17">Then Jesus answered and said, <span class="j">O faithless and perverse generation, how long shall I be with you? how long shall I suffer you? bring him hither to me. </span></verse>
    </chapter></xml>
';

$xml = simplexml_load_string($str);

$verses = $xml->xpath('//verse');


?>
<!DOCTYPE html>
<html lang='en'>
<head>
<title>XML example</title>
<meta charset='utf-8'>
<style type='text/css'>
    .j {
        color: blue;
        font-style: italic;
        font-weight: 600;
    }
</style>
</head>
<body>
        <?php
                foreach ($verses as $v)  {
                    echo "<p>{$v->asXML()}</p>";
                }
        ?>
</body>
</html>

Gives...

image.thumb.png.d2e82ad7223c90f2f130d5c052af129b.png

  • Like 1
Link to comment
Share on other sites

Thank you.... xpath didn't really do what I wanted because of the fact I need to have other attributes above the verse (this is going into a database).... BUT ....asXML() did the trick when combined with my existing code. 

For anyone who may find this helpful, or struggle with the same general thing I did... here is my whole code for parsing this. The KJV.xml file can be found online pretty easily.

 

<?php
$fileName = $_SERVER['DOCUMENT_ROOT'].'/assets/php/kjv.xml';
if (file_exists($fileName)) {
	$xml = simplexml_load_file($fileName);
	foreach($xml->book as $book)
	{
		$bookName = $book['num'];
		foreach($book->chapter as $ch ){
			$verseNum = 1;
			$chapterNum = $ch['num'];
			foreach($ch->verse as $verse){
				echo $bookName.' '.$chapterNum.' '.$verseNum++.' '. $verse->asXML().'<br>';
			}
		}
	}
}
?>

Thank you for your help in this. It is precisely what I needed.

Link to comment
Share on other sites

Not that anyone has been using it this decade - or century, even - but there's a technology that exists which is designed for transforming XML into HTML as you just did. It's called XSLT.

You can do it fully within PHP, but here's a demo without.

kjv.xml

<?xml version="1.0"?>
<?xml-stylesheet href="kjv.xslt" type="text/xsl"?>
<root>
    <book num="I don't know">
        <chapter num="17">
            <verse num="1">And after six days Jesus taketh Peter, James, and John his brother, and bringeth them up into an high mountain apart,</verse>
            <verse num="2">And was transfigured before them: and his face did shine as the sun, and his raiment was white as the light.</verse>
            <verse num="3">And, behold, there appeared unto them Moses and Elias talking with him.</verse>
            <verse num="4">Then answered Peter, and said unto Jesus, Lord, it is good for us to be here: if thou wilt, let us make here three tabernacles; one for thee, and one for Moses, and one for Elias.</verse>
            <verse num="5">While he yet spake, behold, a bright cloud overshadowed them: and behold a voice out of the cloud, which said, This is my beloved Son, in whom I am well pleased; hear ye him.</verse>
            <verse num="6">And when the disciples heard <i>it,</i> they fell on their face, and were sore afraid.</verse>
            <verse num="7">And Jesus came and touched them, and said, <span class="j">Arise, and be not afraid. </span></verse>
            <verse num="8">And when they had lifted up their eyes, they saw no man, save Jesus only.</verse>
            <verse num="9">And as they came down from the mountain, Jesus charged them, saying, <span class="j">Tell the vision to no man, until the Son of man be risen again from the dead. </span></verse>
            <verse num="10">And his disciples asked him, saying, Why then say the scribes that Elias must first come?</verse>
            <verse num="11">And Jesus answered and said unto them, <span class="j">Elias truly shall first come, and restore all things. </span></verse>
            <verse num="12"><span class="j">But I say unto you, That Elias is come already, and they knew him not, but have done unto him whatsoever they listed. Likewise shall also the Son of man suffer of them. </span></verse>
            <verse num="13">Then the disciples understood that he spake unto them of John the Baptist.</verse>
            <verse num="14">And when they were come to the multitude, there came to him a <i>certain</i> man, kneeling down to him, and saying,</verse>
            <verse num="15">Lord, have mercy on my son: for he is lunatick, and sore vexed: for ofttimes he falleth into the fire, and oft into the water.</verse>
            <verse num="16">And I brought him to thy disciples, and they could not cure him.</verse>
            <verse num="17">Then Jesus answered and said, <span class="j">O faithless and perverse generation, how long shall I be with you? how long shall I suffer you? bring him hither to me. </span></verse>
        </chapter>
    </book>
</root>

kjv.xslt

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" />

    <xsl:template match="/">
        <html>
            <body>
                <xsl:apply-templates select="/root/book" />
            </body>
        </html>
    </xsl:template>

    <xsl:template match="book">
        <h1>Book <xsl:value-of select="@num" /></h1>
        <xsl:apply-templates select="chapter" />
    </xsl:template>

    <xsl:template match="chapter">
        <h2>Chapter <xsl:value-of select="@num" /></h2>
        <ol start="{verse[1]/@num}">
            <xsl:apply-templates select="verse" />
        </ol>
    </xsl:template>

    <xsl:template match="verse">
        <li><xsl:apply-templates /></li>
    </xsl:template>

    <xsl:template match="b | i | span">
        <xsl:copy-of select="." />
    </xsl:template>
</xsl:stylesheet>

In a browser, which you might have to run through a webserver depending on your browser security settings,

image.png

(you can see the italics in verses 6 and 14; the spans are invisible but they are present)

  • Great Answer 1
Link to comment
Share on other sites

I have about 10 pounds of old xml books in my office covering all this type of arcana.  Fortunately (or not depending on how you look at it) we have people like Requinix and Barand on this forum, who have the memories of elephants -- quite appropriate given that the elePHant is the official mascot of the PHP project.

  • Like 1
Link to comment
Share on other sites

19 minutes ago, gizmola said:

I have about 10 pounds of old xml books in my office covering all this type of arcana.  Fortunately (or not depending on how you look at it) we have people like Requinix and Barand on this forum, who have the memories of elephants -- quite appropriate given that the elePHant is the official mascot of the PHP project.

I actually use XSLT for some stuff at home: got a lot of data, I manage most it in XML with some in JSON because a real NoSQL database would be awkward to hand-edit like I need, and want to render it into a viewable form. Add XSLT and throw in PHP's function bindings and you can do just about anything. Downside: super inefficient, so complicated processing takes a while.

Early 2000s, give or take, I even experimented with a XML-based website - as in the server responded with XML, not HTML. It worked very well. In fact, after getting back into it for the above project stuff, I'll very likely do it again for a couple smaller projects. Because the simplicity of editing data in XML lets me do whatever I want without having to run a database server or make table schema changes or build CRUD tools.

  • Like 1
Link to comment
Share on other sites

5 hours ago, requinix said:

 

Early 2000s, give or take, I even experimented with a XML-based website - as in the server responded with XML, not HTML. It worked very well. In fact, after getting back into it for the above project stuff, I'll very likely do it again for a couple smaller projects. Because the simplicity of editing data in XML lets me do whatever I want without having to run a database server or make table schema changes or build CRUD tools.

I fought a few xml wars in my day, most involving soap.  Every now and then, some of this comes in handy.     A lot of people working in web development don't realize it wasn't all that long ago that people were arguing over html4 vs xhtml.

Link to comment
Share on other sites

3 hours ago, gizmola said:

I fought a few xml wars in my day, most involving soap.  Every now and then, some of this comes in handy.     A lot of people working in web development don't realize it wasn't all that long ago that people were arguing over html4 vs xhtml.

Oh, SOAP is terrible. Hate it. REST is so much easier to work with.

And yeah, XHTML... I miss that. When it was still a thing, and for a while after, that was what I was using for all my stuff. Then they took all the weirdness of HTML 4 and doubled-down on it with 5. Sigh.

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.