Help required on my script php Dom xml

Messages
92
Reaction score
1
Points
8
Presently I am working on a chart script using fusion power chart for my website. This chart requires xml. I am trying to generate the chart from mysql using php and dom.
the xml appears like this
Code:
<dataset>
<set open="24.6" high="25.24" low="24.58" close="25.19" x="1" volume="17856350"/>
<dataset>
<set open="24.6" high="25.24" low="24.58" close="25.19" x="2" volume="17856350"/>
I have successfully able to fetch data from mysql now I have stucked with two points.

First is in the chart I have to increase x value by 1 for each fetched column. I have tried by count like
Code:
$count=count($row['open']);
$counts=($x<=$count, $x++)
But my problem is if I use count then I have some problem on count I have tried to print the count value by
Code:
$count=count($row['open']);
{
echo $count; 
}
No here If I fetch data from 3 column then count appearing not 3 it's appearing like 111.

And second problem is that I have tried to place the fetched data with foreach in dom like below
Code:
$elements=($row['open']);
foreach($elements as $key=>$value){
$element=$dom->createTextNode($value);
$chart->appendChild($element);
}
But If I do this then I am able to generate xml script but it's only one row value appearing like if fetched 3 rows then one row's value dome getting rest of 2 not.

Can any one tell me how to figure this out. I am not asking for code help I am just asking for the Ideas. I will really appreciate if any one help me about this.
Thanks
 

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
That's not enough information. For example, is $chart rendered as a <dataset> element, or a parent of <dataset>? As it is, there's too much we must guess about, so any specifics we might go into are largely supposition. Code samples should be enough to be complete and to reproduce the problem, but just enough. To be complete, we'll need the table schemata, sample data and a better example of the XML formatted data. You should also indent your code for readability, which can reveal some basic errors.

the xml appears like this
Code:
<dataset>
<set open="24.6" high="25.24" low="24.58" close="25.19" x="1" volume="17856350"/>
<dataset>
<set open="24.6" high="25.24" low="24.58" close="25.19" x="2" volume="17856350"/>
That can't be right. The <dataset> elements aren't closed. What else is missing? You don't necessarily need to show us the whole XML format, but any elements that appear in the PHP code (such as $chart) should definitely appear in the XML. Ellipses and indentation can be used to show that the sample is a fragment. "set" doesn't seem an appropriate tag name for the elements. If it isn't forced on you by the API, change it to something more semantically correct, such as "point", "price" or "stock".

Code:
    ...
    <dataset>
        <point open="24.6" high="25.24" low="24.58" close="25.19" x="1" volume="17856350"/>
        <point open="25.19" high="25.46" low="24.95" close="25.28" x="2" volume="17849533"/>
    </dataset>
    <dataset>
        <point open="13.4" high="13.47" low="13.2" close="13.2" x="1" volume="13488405"/>
        <point open="13.2" high="13.23" low="13.08" close="13.21" x="2" volume="13501861"/>
    </dataset>

PHP:
$count=count($row['open']);

Relational database columns are scalars (also said to be "atomic" or "simple domains"), which means they don't hold compound values (a.k.a aggregate values). Assuming $row is a row fetched from a result, $row['open'] will be a scalar and count($row['open']) will always be 1. This is also why you only get one result row when adding elements to the chart. Each row contains exactly one datapoint, so your code needs to reflect this.

PHP:
    /* The data model's fields shouldn't be defined in the DB query, hence the 
     * $fields, which should come from inspecting the model definition, whatever
     * that is. Here, we inspect a class, which is also used to hold fetched row data.
     */
    // get data from the database
    $fields = get_fields($class);
    $datapoints=$db->prepare("SELECT $fields FROM ... ORDER BY ...");
    $datapoints->execute(...);
    $datapoints->setFetchMode(PDO::FETCH_CLASS, $class);
    // convert data to a document
    foreach ($datapoints as $i => $point) {
        $point->x = $i;
        if (!isset($stocks[$row->stock])) {
            $stock = $stocks[$row->stock] = /* create an <dataset> element */;
            $chart->appendChild($stock);
        } else {
            $stock = $stocks[$row->stock];
        }
        $stock->appendChild(/* convert $point to a <point> element */);
    }
This is actually two tasks (ORM and creating an XML document for later serialization), and should be split into separate functions.

Note the necessity of ordering the results (the ORDER BY clause), as otherwise the results will be in an arbitrary order (likely the primary key order) and the x-values will be incorrect.

As for selecting table columns, the columns should be defined elsewhere to reduce coupling between the model and data storage/retrieval. For example, you could define a class with properties with the same names as the columns, and inspect it to determine which columns to retrieve.
PHP:
// here's one way of getting a list of fields to fetch from the DB
function get_fields($class) {
    return array_keys(get_class_vars($class));
}

// and here's an example class that could be used when fetching rows
class Trading extends Model { // Model also needs to be defined
    public $stock, $open, $high, $low, $close, $volume;
    ...
};

You could make objects responsible for conversion to elements:
PHP:
class Trading extends Model {
    static $tagName='point';
    public $stock, $open, $high, $low, $close, $volume;
    // $stock is the parent, so it isn't an attribute.
    static protected $_nonattr = array('stock' => 1);
    ...
    function toElement() {
        $elt = $doc->createElement(self::$tagName);
        foreach ($this as $field => $value) {
            if (! isset(self::$_nonattr[$field])) {
                $elt->setAttribute($field, $value);
            }
        }  
        return $elt;
    }
};
Or you could create a separate class that maps Trading to elements, à la data mappers ([2], [3]). Data mappers are potentially more flexible, but also a more advanced topic. The first PHP code in this post could be a fragment of a data mapper.
 
Last edited:
Messages
92
Reaction score
1
Points
8
I almost figure this out except one. can any one tell me in which function the script is written. Because I do not know it and this is the way to solve this puzzle. The code is right below.
Code:
$_xml ="<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n";

 $_xml .="<site>\r\n";

 while ($row = mysql_fetch_assoc($result)) {

 if ($row["name"]) {

 $_xml .="\t<page title=\"" . $row["name"] . "\">\r\n";



$_xml .="\t</page>\r\n";
 } else {

 $_xml .="\t<page title=\"Nothing Returned\">\r\n";
$_xml .="\t\t<file>none</file>\r\n";

 $_xml .="\t</page>\r\n";
 } }

 $_xml .="</site>";

 fwrite($file, $_xml);

 fclose($file);
 

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
I'm sorry, I don't understand what the problem is supposed to be in your most recent post. To which script and function are you referring?
 
Last edited:
Messages
92
Reaction score
1
Points
8
I'm sorry misson. Actually your previous post was little hard for me because I am not a php expert :D. \but how ever I found I am able to take count of rows and increase the x value by this
PHP:
$num_rows = mysql_num_rows($result);
for($a=0; $a<sizeof($numb_rows); a++)
And I can increase the x value.

Now I found a Tutorial about php to xml from mysql from here http://articles.techrepublic.com.com/5100-10878_11-5035149.html

overall code stands like
PHP:
<?php
$connection = mysql_connect("localhost", "newdbusr", "newdbusrpassword") or die("Could not connect.");
$table_name = 'friends';
$db = mysql_select_db("mynewdb");
$query = "select * from " . $table_name;

$result = mysql_query($query, $connection) or die("Could not complete database query");
$num = mysql_num_rows($result);
if ($num != 0) {

 $file= fopen("results.xml", "w");

 $_xml ="<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n";

 $_xml .="<site>\r\n";

 while ($row = mysql_fetch_assoc($result)) {

 if ($row["name"]) {

 $_xml .="\t<page title=\"" . $row["name"] . "\">\r\n";

 $_xml .="\t\t<file>" . $row["pet"] . "</file>\r\n";
$_xml .="\t</page>\r\n";
 } else {

 $_xml .="\t<page title=\"Nothing Returned\">\r\n";
$_xml .="\t\t<file>none</file>\r\n";

 $_xml .="\t</page>\r\n";
 } }

 $_xml .="</site>";

 fwrite($file, $_xml);

 fclose($file);

 echo "XML has been written.  <a href=\"results.xml\">View the XML.</a>";

 } else {

 echo "No Records found";

 } ?>
It's working. NOw I learned dome as creating elements, attribute, and text node in here author has created none and Completed it without writing so much. The problem is I can not Identify this function becaue I did not learned it and never knew it. So if I can learn this I can complete this without writing so much. Hope you can understand that writing so much thing is good but when found some error or bug then It's very difficult to find out. So I asked.
I am sorry for the English I am not a good writer.
 

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
PHP:
$num_rows = mysql_num_rows($result);
for($a=0; $a<sizeof($numb_rows); a++)
You shouldn't use sizeof here. sizeof (like count) return the number of items in an array. for loops (make sure you read that documentation) loop over values, typically a range of integers, but any finite, computable sequence would work:
PHP:
for ($x=0;  $x < 10;      $x += 2) {/* even whole numbers < 10 */}
for ($x=1;  $x <= 0x4000; $x *= 2) {/* powers of 2: 1, 2, 4, 8, ..., 16384 */}
for ($x=27; $x != 1;      $x = ($x&1 ? ($x >> 1) : (3*$x+1))) {/* a Collatz sequence */}

To loop over items with for, you instead loop over a range and use them as indices. count and sizeof give you an upper bound for the range. Here, mysql_num_rows gives you the upper bound, which you store in $num_rows. Thus, you'd simply use $num_rows as the upper bound:
PHP:
$num_rows = mysql_num_rows($result);
for ($a=0; $a < $num_rows; ++$a)

With PDO (which is superior in many ways) rather than the outdated mysql extension, you can use foreach to loop over the results (as my first code sample illustrates). For a PDO tutorial, try "Writing MySQL Scripts with PHP and PDO".

Now I found a Tutorial about php to xml from mysql from here http://articles.techrepublic.com.com/5100-10878_11-5035149.html
Not a great tutorial, as it doesn't follow best practices. Also, code used in tutorials usually isn't fit for production.

PHP:
<?php
$connection = mysql_connect("localhost", "newdbusr", "newdbusrpassword") or die("Could not connect.");
Creating a DB connection in multiple scripts makes your site less secure (as you must put user credentials in each script) and susceptible to typos. Create a class or a function to take care of DB connections so you can isolate sensitive information in a single place. It doesn't need to be anything complex; you can start with LocalDB.

As for how the rest of the script from the tutorial works, it simply generates XML as a string (XML is, after all, just text, at a certain level), similar to how PHP is usually used to generate HTML. The script then writes the string to a file, rather than to standard output. To deal with files, it uses fopen, fwrite and fclose. In pseudo code:

  1. Open DB connection
  2. Query DB
  3. If there are results:
    1. Open a file to store the XML
    2. Create XML header
    3. For each result row:
      1. If row has a name, output a page element (with the name) containing a file element.
      2. Else output a page element (with a default name name) containing a file element.
    4. Create XML footer
    5. Write XML string to a file.
    6. Close the file.
  4. Else there are no results, so inform the user.


I am sorry for the English I am not a good writer.
Don't worry about it. You write English much better than I'd write in your language. Non-English speakers get a pass when it comes to writing properly.
 
Top