Fetch data from .USX file using php - php

I have one .usx file and i want to fetch data from it accordingly. But now finding any way to do it. Please help me out.
usx file link
I had tried the below code
$xml=simplexml_load_file("uploads/American-Standard-Version-Bible-master/usx/01-GEN.usx") or die("Error: Cannot create object");
foreach($xml->children() as $book)
{
// echo "<pre>";
// print_r($book);
echo "Book Name:".$book->attributes()->code."<br/>";
if($book->attributes()->number != "" )
{
echo "chapter : ".$book->attributes()->number."<br />";
}
foreach ($book->verse as $value) {
// echo "<pre>";
// print_r($value);
echo "Verses Number : ".$value->attributes()->number."<br />";
}
echo "book : ".$book."<br />";
echo "<hr/>";
}
}
OUTPUT :
I want output one by one of all verse rather then all at once

The problem can be that SimpleXML just doesn't give you enough control over XML that has more than a simple structure. So trying to get the text inbetween the <verse> tags is difficult. If instead you use DOMDocument, this has much more detail and control over your document.
The code below just reads through the document and mostly checks the node names to work out what it should be displaying - so for the <chapter> element, it will output the number attribute. The only difference is that when looking through the main <para> elements which contain the <verse> and text mixed together, it looks for a node type of XML_TEXT_NODE, which as you might expect is the verse text, so it just outputs the contents at that point.
$dom = new DOMDocument();
$dom->preserveWhiteSpace = false;
$dom->load("01-GEN.usx");
foreach ( $dom->documentElement->childNodes as $element ) {
if ( $element->nodeName == "book" ) {
echo "Book Name:".$element->getAttribute("code")."<br/>";
}
else if ( $element->nodeName == "chapter" ) {
echo "chapter:".$element->getAttribute("number")."<br/>";
}
else if ( $element->nodeName == "para" ) {
foreach ( $element->childNodes as $verse ) {
if ( $verse->nodeName == "verse" ) {
echo "verse:".$verse->getAttribute("number")."<br/>";
}
else if ( $verse->nodeType == XML_TEXT_NODE ) {
echo $verse->nodeValue."<br/>";
}
}
}
}

Related

How to check table tr th/td exist in the page, php

I am trying to verify table tr th/td or dl dt/dd exist or not in the page. So I tried to do something like below.
foreach($links as $k => $val){
$html = file_get_contents($val);
if (strpos($val, "</table>") !== false) {
echo "table exist";
}
elseif(strpos($val, "</dl>")!== false){
echo "dl exist";
}
}
But it's not working. Any possible way to verify html has certain elements? Or is html has certain amount elements. for example more than 5 th or more than 5 dd
You can use getElementsByTagName of DOM
$dom = new DOMDocument();
$dom->loadHTMLFile('filename.html');
$tableRow = $dom->getElementsByTagName('tr');
foreach ($tableRow as $tr) {
echo $tr->nodeValue;
echo $tableRow->length;
}

Failed loading XML:xmlParseCharRef: invalid xmlChar value

When I try to Import xml file, it returns an error:
xmlParseCharRef: invalid xmlChar value 4" because of $amp; in xml <STOCKGROUP >NAME="ABC & Glass" RESERVEDNAME="">
Here is code I'm using to read xml file data
function add_product_type()
{
print_r($_FILES);
if (isset($_FILES['product_type_file']) && ($_FILES['product_type_file']['error'] == UPLOAD_ERR_OK)) {
$use_errors = libxml_use_internal_errors(true);
$response = simplexml_load_file($_FILES['product_type_file']['tmp_name']);
print_r($response);
foreach($response->BODY->IMPORTDATA as $key => $value) {
foreach($value->REQUESTDATA->TALLYMESSAGE as $key => $values) {
if (strstr("&", $values->STOCKGROUP->attributes())) {
$name = str_replace("&", "&", $values->STOCKGROUP->attributes());
}
else {
$name = $values->STOCKGROUP->attributes();
}
echo $name . ",";
}
}
if ($response == false) {
echo "Failed loading XML\n";
foreach(libxml_get_errors() as $error) {
echo "\t", $error->message;
}
}
}
}
XML has no notion of HTML entities. As a hack, you can decode the entities first with
$html = html_entity_decode($file_contents, ENT_QUOTES, "utf-8");
and then try parse $html with the XML parser. Just hope it's tolerant enough, because HTML is still not valid XML.
The good news is that you can then remove the if (strstr("&", hack because that is taken care of by html_entity_decode().
Your XML sample isn't the same data as your getting the error with and processes OK, but this doesn't mean that your code is correct. In
your main loop, you use $values->STOCKGROUP->attributes() as the name, but if you did a print_r() of this value, you will see it comes out with a list of all of the attribute values and your code will combine them all into one string.
SimpleXMLElement Object
(
[#attributes] => Array
(
[NAME] => Alluminium Section & Glass
[RESERVEDNAME] =>
)
)
If you just want the NAME attribute of <STOCKGROUP NAME="Alluminium Section & Glass" RESERVEDNAME="">, then use STOCKGROUP['NAME']. Also rather than just substitute &, use html_entity_decode() to convert any characters in the name.
foreach($response->BODY->IMPORTDATA as $key => $value) {
foreach($value->REQUESTDATA->TALLYMESSAGE as $key => $values) {
$name = html_entity_decode((string)$values->STOCKGROUP['NAME']);
echo $name . ",";
}
}
This code with the sample you provide outputs...
Alluminium Section & Glass,
Update:
Check the file being loaded...
$data = file_get_contents($_FILES['product_type_file']['tmp_name']);
echo $data;
$use_errors = libxml_use_internal_errors(true);
$response = simplexml_load_string($data);
echo $response->asXML();

PHP Simple HTML DOM - method find retrieve empty array

Now I am trying to write a PhP parser and I don't why my code return an empty array. I am using PHP Simple HTML DOM. I know my code is't perfect, but it's only for testing.
I will be appreciate for any help
public function getData() {
// get url form urls.txt
foreach ($this->list_url as $i => $url) {
// create a DOM object from a HTML file
$this->html = file_get_html($url);
// find array all elements with class="name" because every products having name
$products = $this->html->find(".name");
foreach ($products as $number => $product) {
// get value attr a=href product
$href = $this->html->find("div.name a", $number)->attr['href'];
// create a DOM object form a HTML file
$html = file_get_html($href);
if($html && is_object($html) && isset($html->nodes)){
echo "TRUE - all goodly";
} else{
echo "FALSE - all badly";
}
// get all elements class="description"
// $nodes is empty WHY? Tough web-page having content and div.description?
$nodes = $html->find('.description');
if (count($nodes) > 0) {
$needle = "Производитель:";
foreach ($nodes as $short_description) {
if (stripos($short_description->plaintext, $needle) !== FALSE) {
echo "TRUE";
$this->data[] = $short_description->plaintext;
} else {
echo "FALSE";
}
}
} else {
$this->data[] = '';
}
$html->clear();
unset($html);
}
$this->html->clear();
unset($html);
}
return $this->data;
}
hi you should inspect the element and copy->copy selector and use it in find method to getting the object

PHP: $_POST array to XML file and display results

I'm creating a "Madlibs" page where visitors can create funny story things online. The original files are in XML format with the blanks enclosed in XML tags
(Such as blablabla <PluralNoun></PluralNoun> blablabla <Verb></Verb> ).
The form data is created using XSL and the results are saved using a $_POST array. How do I post the $_POST array between the matching XML tags and then display the result to the page? I'm sure it uses a "foreach" statement, but I'm just not familiar enough with PHP to figure out what functions to use. Any help would be great.
Thanks,
E
I'm not sure if I understood your problem quite well, but I think this might help:
// mocking some $_POST variables
$_POST['Verb'] = 'spam';
$_POST['PluralNoun'] = 'eggs';
// original template with blanks (should be loaded from a valid XML file)
$xml = 'blablabla <PluralNoun></PluralNoun> blablabla <Verb></Verb>';
$valid_xml = '<?xml version="1.0"?><xml>' . $xml . '</xml>';
$doc = DOMDocument::loadXML($valid_xml, LIBXML_NOERROR);
if ($doc !== FALSE) {
$text = ''; // used to accumulate output while walking XML tree
foreach ($doc->documentElement->childNodes as $child) {
if ($child->nodeType == XML_TEXT_NODE) { // keep text nodes
$text .= $child->wholeText;
} else if (array_key_exists($child->tagName, $_POST)) {
// replace nodes whose tag matches a POST variable
$text .= $_POST[$child->tagName];
} else { // keep other nodes
$text .= $doc->saveXML($child);
}
}
echo $text . "\n";
} else {
echo "Failed to parse XML\n";
}
Here is PHP foreach syntax. Hope it helps
$arr = array('fruit1' => 'apple', 'fruit2' => 'orange');
foreach ($arr as $key => $val) {
echo "$key = $val\n";
}
and here is the code to loop thru your $_POST variables:
foreach ($_POST as $key => $val) {
echo "$key = $val\n";
// then you can fill each POST var to your XML
// maybe you want to use PHP str_replace function too
}

How to get only required xpath elements?

I have an xml file that I want to store a node's rank attribute in a variable.
I tried:
echo $var = $xmlobj->xpath("//Listing[#rank]");
to no avail, it just prints ArrayArray.
How can this be done?
if($xmlobj = simplexml_load_string(file_get_contents($xml_feed)))
{
foreach($xmlobj as $listing)
{
// echo 'Session ID: ' . $sessionId = $listing->sessionId . '<br />';
// echo 'Result Set: ' . $ResultSet = $listing->ResultSet . '<br />';
print_r($xmlobj->xpath("//Listing[#rank]"));
// $result = $xmlobj->xpath("/page/");
// print_r($result);
}
}
Henrik's suggestion:
foreach($xmlobj as $listing)
{
$var = $xmlobj->xpath("//Listing[#rank]");
foreach ($var as $xmlElement)
{
echo (string)$xmlElement;
}
}
Here you go
<page>
<ResultSet id="adListings" numResults="3">
<Listing rank="1" title="Reliable Local Moving Company" description="TEST." siteHost="www.example.com">
</Listing>
Edit after playing around with the posted example xml:
My initial answer was somewhat off track - casting to string would give you the inner text of the selected elements, if they have one (not the case here)
"//Listing[#rank]" selects all 'Listing' Elements that have a 'rank' attribute. If you want to select the attributes themselves, use "//Listing/#rank"
To output an attribute, use the SimpleXMLElement with array syntax: $xmlElement['rank']
So in your case:
foreach($xmlobj as $listing)
{
$var = $xmlobj->xpath("//Listing/#rank");
foreach ($var as $xmlElement)
{
echo $xmlElement['rank'];
}
}
or
foreach($xmlobj as $listing)
{
$var = $xmlobj->xpath("//Listing[#rank]");
foreach ($var as $xmlElement)
{
echo $xmlElement['rank'];
echo $xmlElement['title']; // Added to demonstrate difference
}
}
should work.
In the first case, the $xmlElement would only contain the 'rank' attribute while in the second, it would contain the complete 'Listing' element (hence allowing the title output).

Categories