0

I want to display the xml content differentiating the docs by fields names and values any help please.. Below is my xml file content..

<doc>
    <field name="id">1</field>
    <field name="name">A</field>
    <field name="sk">Acce</field>
    <field name="level">Beginner</field>
    <field name="do">Tuto</field>
    <field name="open">1</field>
    <field name="type">Ct</field>
    <field name="extensis">cl_ex</field>
    <field name="features">Atos</field>
    <field name="downl"></field>
    <field name="source">AtomicCounters</field>
    <field name="description">Ths.</field>
    <field name="tag1"></field>
    <field name="tag2"></field>
    <field name="tag3"></field>
    <field name="tag4">Global</field>
    <field name="tag5">Atomic</field>
    <field name="tag6"></field>
    <field name="tag7"></field>
    <field name="tag8"></field>
    <field name="tag9"></field>
    <field name="tag10"></field>
  </doc>

  <doc>
    <field name="id">2</field>
    <field name="name">Ar</field>
    <field name="sk">Acrce</field>
    <field name="level">Beginner</field>
    <field name="do">Tuto1</field>
    <field name="open">11</field>
    <field name="type">C1t</field>
    <field name="extensis">cl_exd</field>
    <field name="features">Atos</field>
    <field name="downl"></field>
    <field name="source">ddddd</field>
    <field name="description">Thsdd.</field>
    <field name="tag1"></field>
    <field name="tag2"></field>
    <field name="tag3"></field>
    <field name="tag4">Global1</field>
    <field name="tag5">Atomic1</field>
    <field name="tag6"></field>
    <field name="tag7"></field>
    <field name="tag8"></field>
    <field name="tag9"></field>
    <field name="tag10"></field>
  </doc>

Below is the code I am using..

 <?php
    $result="";
    $document = new DOMDocument();
    //$document->load('/wamp/www/amd/261013/test/amd_one.xml');
    $document->load('http://localhost/solr/select');



    // this will also output doctype and comments at top level
    foreach($document->childNodes as $node)
       $result[] .= $document->saveXML($node)."\n";

    //echo $result[];

    foreach($result as $key => $value)
    {
      echo "$key - $value<br/>";
    }

    ?>

However it is values only... like 1 Ar Acce....

I want like $field = id, $value = 1,$field = name, $value = A, $field = id, $value = 2,$field = name, $value = Ar,..

Any sugesstions please..

Indudhara Gs
  • 11
  • 1
  • 9
  • Use the view-source functionality of your browser to actually learn about what exactly you are outputting. And you don't need to convert to array here actually. Not doing so does already prevent you doing the error in the first place. Please elaborate your code-example. – hakre Oct 26 '13 at 18:44
  • The link you had active in your code does not have `field` but `str` elements so there is a slight mismatch in your description. – hakre Oct 26 '13 at 18:48

2 Answers2

0

This is not about key and value, but about the name-attribute of the <field>-node and its value.

Example using simplexml:

$xml = simplexml_load_string($x); // assume XML in $x

foreach ($xml->doc as $doc) {
    foreach ($doc->field as $field) echo "$field[name]: $field <br />";
    echo "------ <br />";
}

see it working: http://codepad.viper-7.com/k3zg8I

michi
  • 6,565
  • 4
  • 33
  • 56
0

You have some issues in your code. First of all, you do not really need to convert into an (you can, but for getting things started only do as little as necessary). Also there are some points I guess you didn't know about, so here are some pointers on your code:

You write:

foreach ($document->childNodes as $node)

But actually you're only interested in <doc> elements so far. Let's do this:

foreach ($document->getElementsByTagName('doc') as $node)

This variant will actually give you only the <doc> elements you're interested in for $node.

Then the next problem you have is to convert the <field> (in my answer called <str>) elements with their name attribute and their node-value into a $key => $value pair. I'd say this is best done with a little helping mapping function, so that you can apply the transformation more fluently. Let's create such a mapping function:

$keyValue = function (DOMElement $element)
{
    return [
        $element->getAttribute('name'), // key
        trim($element->nodeValue),      // value
    ];
};

This is a small function that turns a DOMElement object into an array having key as the first entry (by reading out the attribute name) and value as the second entry (by reading the node-value). It is a pretty simple function.

This function now can be applied within the loop of the $docs elements and further down of all <str> child-elements:

foreach ($document->getElementsByTagName('doc') as $node)
{
    foreach ($node->getElementsByTagName('str') as $field)
    {
        list($key, $value) = $keyValue($field);
        echo "\$key: $key - \$value: $value\n";
    }
}

As this chunk shows, after iterating over the <doc> elements, you iterate over each their descendant elements named <str> (<field> in your question). Onto each of these the mapping function $keyValue() is applied and you get the $key and $value variable from the mapping functions return value.

Note: If you need the child-node traversal more specific, please see for filtered childnode traversal in PHP DOMDocument and similar for some more ideas how you can iterate over DOMNodeList and friends.

Let's run the example to test if it works:

1. Node:
========
$key: id - $value: 3
$key: name - $value: BinarySearch
$key: sdk - $value: Accelerated Parallel Process
$key: level - $value: Beginner
$key: domain - $value: 
...
2. Node:
========
$key: id - $value: 2
$key: name - $value: BasicDebug
$key: sdk - $value: Accelerated Parallel Process
$key: level - $value: Beginner
$key: domain - $value: Debug
...
3. Node:
========
$key: id - $value: 1
$key: name - $value: AtomicCounters
$key: sdk - $value: Accelerated Parallel Process
$key: level - $value: Beginner
$key: domain - $value: Tutorial
...
4. Node:
========
$key: id - $value: 4
$key: name - $value: BinomialOption
$key: sdk - $value: Accelerated Parallel Process
$key: level - $value: Beginner
$key: domain - $value: Financial Engineering
...
5. Node:
========
$key: id - $value: 5
$key: name - $value: BinomialOptionMultiGPU
$key: sdk - $value: Accelerated Parallel Process
$key: level - $value: Intermediate
$key: domain - $value: Financial Engineering
...
6. Node:
========
$key: id - $value: 6
$key: name - $value: BitonicSort
$key: sdk - $value: Accelerated Parallel Process
$key: level - $value: Beginner
$key: domain - $value: General
...
7. Node:
========
$key: id - $value: 7
$key: name - $value: BlackScholes
$key: sdk - $value: Accelerated Parallel Process
$key: level - $value: Intermediate
$key: domain - $value: Financial Engineering
...
8. Node:
========
$key: id - $value: 8
$key: name - $value: BlackScholesDP
$key: sdk - $value: Accelerated Parallel Process
$key: level - $value: Intermediate
$key: domain - $value: Financial Engineering
...
9. Node:
========
$key: id - $value: 9
$key: name - $value: BoxFilter
$key: sdk - $value: Accelerated Parallel Process
$key: level - $value: Intermediate
$key: domain - $value: Image Processing
...
10. Node:
========
$key: id - $value: 10
$key: name - $value: BoxFilterGL
$key: sdk - $value: Accelerated Parallel Process
$key: level - $value: Intermediate
$key: domain - $value: Image Processing
...

And this looks like the result you were looking for. Here the exact code used in that example:

<?php
/**
 * How to display value with field names from Solr XML files, getting values only
 *
 * @link https://stackoverflow.com/q/19605287/367456
 */

$file = "solr.xml";

if (!file_exists($file))
{
    $url    = 'http://index.websolr.com/solr/15b84f04a7e/select';
    $handle = fopen($url, 'r');
    file_put_contents($file, $handle);
    fclose($handle);
}

$document = new DOMDocument();
$document->load($file);

$keyValue = function (DOMElement $element)
{
    return [
        $element->getAttribute('name'), // key
        trim($element->nodeValue), // value
    ];
};


foreach ($document->getElementsByTagName('doc') as $node)
{
    foreach ($node->getElementsByTagName('str') as $field)
    {
        list($key, $value) = $keyValue($field);
        echo "\$key: $key - \$value: $value\n";
    }
}


foreach ($document->getElementsByTagName('doc') as $index => $node)
{
    printf("%d. Node:\n========\n", $index + 1);
    foreach ($node->getElementsByTagName('str') as $count => $field)
    {
        if ($count > 4)
        {
            echo "...\n";
            break;
        }

        list($key, $value) = $keyValue($field);
        echo "\$key: $key - \$value: $value\n";
    }
}
Community
  • 1
  • 1
hakre
  • 193,403
  • 52
  • 435
  • 836