2

thank you for your assistance in advance. I have search through this forum and through the www looking for an answer to this but cannot find a straight forward one.

I am simply trying to return results from an XML File that only extracts the unique value of an attribute.

XML Example File:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<computers>
    <restults>
   <computer id="1" group_id="a" model_group="acer" name="Acer 1 GB" />
   <computer id="2" group_id="a" model_group="acer" name="Acer 2 GB" />
   <computer id="3" group_id="b" model_group="acer" name="Acer 3 GB" />
   <computer id="4" group_id="c" model_group="acer" name="Acer 4 GB"/>
   <computer id="5" group_id="c" model_group="acer" name="Acer 6 GB" />
   <computer id="6" group_id="d" model_group="acer" name="Acer 8 GB" />
   <computer id="7" group_id="d" model_group="acer" name="Acer 16 GB" />
   <computer id="8" group_id="d" model_group="acer" name="Acer 32 GB" />
   <computer id="9" group_id="e" model_group="acer" name="Acer 48 GB" />
    </restults>
</computers>

What I want is for the php script to run through the XML file and only present me with the unique "group_id" values. ie: a,b,c,d,e

Nothing more.

I've looked at various solutions, provided on this website and others, but they just haven't worked.

I did read up about Xpath functions and the distinct-values function but I cannot find a way to identify what version of Xpath I am running? I do know that this function is only available in Xpath 2.0

Satish Sharma
  • 9,547
  • 6
  • 29
  • 51
RonaldZN
  • 43
  • 1
  • 7

1 Answers1

1

Using only XPath 1.0 the only solution I know of is to check all previous nodes for the same value and if found exclude this node.

<?php
$e = new SimpleXMLElement(data());
foreach( $e->xpath('/computers/restults/computer[not(@group_id=preceding-sibling::computer/@group_id)]/@group_id') as $n ) {
    echo $n, "\n";
}

function data() {
    return <<< eox
<computers>
    <restults>
        <computer id="1" group_id="a" model_group="acer" name="Acer 1 GB" />
        <computer id="2" group_id="a" model_group="acer" name="Acer 2 GB" />
        <computer id="3" group_id="b" model_group="acer" name="Acer 3 GB" />
        <computer id="4" group_id="c" model_group="acer" name="Acer 4 GB"/>
        <computer id="5" group_id="c" model_group="acer" name="Acer 6 GB" />
        <computer id="6" group_id="d" model_group="acer" name="Acer 8 GB" />
        <computer id="7" group_id="d" model_group="acer" name="Acer 16 GB" />
        <computer id="8" group_id="d" model_group="acer" name="Acer 32 GB" />
        <computer id="9" group_id="e" model_group="acer" name="Acer 48 GB" />
    </restults>
</computers>
eox;
}

when using XSLT < 2.0 there is a method called Muenchian grouping which could be helpful here.

I haven't tested both approaches against large data sets. They might be rather time/memory consuming....

VolkerK
  • 95,432
  • 20
  • 163
  • 226
  • Hi There Volkerk. Thank you, that worked brilliantly. It is slow on larger files, but it did the trick. Thank You. – RonaldZN Mar 04 '13 at 10:45