skip to Main Content

I want to search title in this object and if find the title get link:

array(1) {
  ["item"]=>
  array(13892) {
    [0]=>  object(SimpleXMLElement)#2 (6) {
      ["part"]=> string(1) "0"
      ["search"]=> string(15) "Superfrog Disk1"
      ["rom_console"]=> string(1) "6"
      ["title"]=> string(107) "<span class="iconochive-Uplevel" title="Parent Directory" aria-hidden="true"></span> Go to parent directory"
      ["link"]=> string(75) "https://archive.org/download/3ds-main-encrypted//details/3ds-main-encrypted"
      ["id"]=> object(SimpleXMLElement)#13894 (0) {}
    }
    [1]=> object(SimpleXMLElement)#3 (6) {
      ["part"]=> string(1) "0"
      ["search"]=> string(15) "Superfrog Disk1"
      ["rom_console"]=> string(1) "6"
      ["title"]=> string(53) "100% Pascal Sensei - Kanpeki Paint Bombers (Japan).7z"
      ["link"]=> string(121) "https://archive.org/download/3ds-main-encrypted/100%25%20Pascal%20Sensei%20-%20Kanpeki%20Paint%20Bombers%20%28Japan%29.7z"
      ["id"]=> object(SimpleXMLElement)#13894 (0) {}
    }
  }
}

Here is what I try:


$myXMLData = file_get_contents('file.txt');
$xml=simplexml_load_string($myXMLData) or die("Error: Cannot create object");


function _xml2array ( $xmlObject, $out = array () ){
    foreach ( (array) $xmlObject as $index => $node )
        $out[$index] = ( is_object ( $node ) ) ? _xml2array ( $node ) : $node;

    return $out;
}

function find_role($object, $id) {
    foreach ($object->item as $inside_object) {
        if ($id == $inside_object->title) {
            return $inside_object->link;
        }
    }
    return false;
}

$objectxx = _xml2array($xml);
echo find_role($objectxx, "100% Pascal Sensei - Kanpeki Paint Bombers (Japan).7z");

In the file.txt I have somthing like this:

<?xml version="1.0"?>
<ArrayOfItem xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <item>
    <part>0</part>
    <search>Superfrog Disk1</search>
    <rom_console>6</rom_console>
    <title>&lt;span class="iconochive-Uplevel" title="Parent Directory" aria-hidden="true"&gt;&lt;/span&gt; Go to parent directory</title>
    <link>https://archive.org/download/3ds-main-encrypted//details/3ds-main-encrypted</link>
    <id />
  </item>
  <item>
    <part>0</part>
    <search>Superfrog Disk1</search>
    <rom_console>6</rom_console>
    <title>100% Pascal Sensei - Kanpeki Paint Bombers (Japan).7z</title>
    <link>https://archive.org/download/3ds-main-encrypted/100%25%20Pascal%20Sensei%20-%20Kanpeki%20Paint%20Bombers%20%28Japan%29.7z</link>
    <id />
  </item>
  <item>
    <part>0</part>
    <search>Superfrog Disk1</search>
    <rom_console>6</rom_console>
    <title>View Contents</title>
    <link>https://archive.org/download/3ds-main-encrypted/100%25%20Pascal%20Sensei%20-%20Kanpeki%20Paint%20Bombers%20%28Japan%29.7z/</link>
    <id />
  </item>
</ArrayOfItem>

2

Answers


  1. If you tried to use the SimpleXML library properly, you would simplify your code a lot.

    Firstly, you can load the file directly rather than having to read the file and then decode the element. Mainly that you can use object notation to access elements inside another element (i.e. $item->title), so you don’t need to convert the data to arrays all the time.

    Something like

    $xml = simplexml_load_file('a.xml');
    
    function find_role($xml, $id)
    {
        foreach ($xml->item as $item) {
            if ($id == $item->title) {
                return (string)$item->link;
            }
        }
        return false;
    }
    
    echo find_role($xml, '100% Pascal Sensei - Kanpeki Paint Bombers (Japan).7z');
    

    The only real complication is that each item is a SimpleXMLElement, so sometimes you need to cast it to a string to make sure you get the value and not the object (as in return (string)$item->link;).

    As a sub note – you can also use XPath to find the elements for you, but that may be beyond the scope of what you are trying to do.

    Login or Signup to reply.
  2. You can also use XPath:

    $myXMLData = file_get_contents('file.txt');
    $xml=simplexml_load_string($myXMLData) or die("Error: Cannot create object");
        
    $title = '100% Pascal Sensei - Kanpeki Paint Bombers (Japan).7z';
    $item = current($xml->xpath("//item[title='$title']"));
    
    echo (string) $item?->link;
    

    Or create your own class:

    $myXMLData = file_get_contents('file.txt');
    $library = simplexml_load_string($myXMLData, Library::class) or die("Error: Cannot create object");
        
    echo $library->findRole('100% Pascal Sensei - Kanpeki Paint Bombers (Japan).7z');
    
    class Library extends SimpleXMLElement
    {
        public function findRole(string $title): ?string
        {
            $item = current($this->xpath("//item[title='$title']"));
    
            return $item ? (string) $item->link : null;
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search