1

I'm struggling to append an child node within an XML file with a static unique ID.

The XML feed I'm working with is hosted on a server elsewhere and can only be accessed via its URL.

Said feed follows this sort of pattern:

<?xml version="1.0" encoding="UTF-8"?>
<properties>
    <property>
        <title>Some Sunny Place</title>
        <address>Some Building, Somewhere, Really Nice</address>
    </property>
    <property>
        <title>Some Rainy PLace Place</title>
        <address>Some Gutter, Somewhere, Not So Nice</address>
    </property>
</properties>

What I'm trying to achieve is using the URL from the feed is add a unique id to the 'property' node and output the XML feed at an alternate URL.

e.g. example.com/proeprty-feed contains feed without ID. Add the ID using PHP and output the feed to something.com/property-feed

<?xml version="1.0" encoding="UTF-8"?>
<properties>
    <property upid=123456>
        <title>Some Sunny Place</title>
        <address>Some Building, Somewhere, Really Nice</address>
    </property>
    <property upid=abcdef>
        <title>Some Rainy PLace Place</title>
        <address>Some Gutter, Somewhere, Not So Nice</address>
    </property>
</properties>

What I have tried is input.php

<?php
$xmlstr = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<properties>
    <property>
        <title>Some Sunny Place</title>
        <address>Some Building, Somewhere, Really Nice</address>
    </property>
    <property>
        <title>Some Rainy PLace Place</title>
        <address>Some Gutter, Somewhere, Not So Nice</address>
    </property>
</properties>
XML;
?>

And output.php

<?php

include 'input.php';

$sxe = new SimpleXMLElement($xmlstr);
$sxe->addAttribute('upid', uniqid('prop-'));

echo $sxe->asXML();

?>

But this outputs:

<properties upid="prop-5ac7c06a39ddd">
    <property>
        <title>Some Sunny Place</title>
        <address>Some Building, Somewhere, Really Nice</address>
    </property>
    <property>
        <title>Some Rainy PLace Place</title>
        <address>Some Gutter, Somewhere, Not So Nice</address>
    </property>
</properties>

2 Answers2

3

Something along the lines of this:

<?php

$string = '<?xml version="1.0" encoding="UTF-8"?>
<properties>
    <property>
        <title>Some Sunny Place</title>
        <address>Some Building, Somewhere, Really Nice</address>
    </property>
    <property>
        <title>Some Rainy PLace Place</title>
        <address>Some Gutter, Somewhere, Not So Nice</address>
    </property>
</properties>';
$xml = new SimpleXMLElement($string);

for($i = 0; $i < count($xml -> property); $i++) {
    $xml -> property[$i] -> addAttribute('upid', uniqid());
}
header('Content-Type: text/xml');
print $xml -> asXml();
user9189147
  • 296
  • 1
  • 7
  • Sweet! Thanks for the help. How do I apply this to an XML feed that is available via a third party URL g.g. example.com/property-feed I had looked at adding more_entropy, but couldn't get past adding the ID to the child node. – Dave Pearce Apr 06 '18 at 18:36
  • I am not sure of your particular use case. What are you trying to do with the XML from the external server? Is this some that is loaded frequently, one time, etc... Give some more details and I'd be happy to respond. – user9189147 Apr 06 '18 at 18:46
  • Basically, I'm given an XML feed from a third party server, which I have permission for using. It contains approximately 4,000 properties. But none of the properties have any ID. I'm wanting to use my server, to add the ID and then I can export the XML feed from my server with the ID. This use is permitted. I have revised my question if it lends any further insight. – Dave Pearce Apr 06 '18 at 18:48
  • You could grab the file, update the xml using the code below, and then save the string to a file on your local server. See CURL, or file_get_contents, to grab the external file. See file_put_contents, or fopen -> fwrite -> fclose. See: https://stackoverflow.com/questions/26876446/download-external-file-with-php-fopen-and-or-curl?rq=1 – user9189147 Apr 06 '18 at 18:53
  • No need to use cURL. opted for simplexml_load_file and combined it with your snippet. ` property); $i++) { $xml -> property[$i] -> addAttribute('upid', uniqid('upid-')); } header('Content-Type: text/xml'); print $xml -> asXml();` – Dave Pearce Apr 06 '18 at 21:10
  • Happy you got it figured out. Sometimes access to remote files is disabled on the server. So , file_get_contents and simplexml_load_file won’t work with remote files. If that’s the case, use CURL. – user9189147 Apr 06 '18 at 21:16
0
<?php
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<properties>
    <property>
        <title>Some Sunny Place</title>
        <address>Some Building, Somewhere, Really Nice</address>
    </property>
    <property>
        <title>Some Rainy PLace Place</title>
        <address>Some Gutter, Somewhere, Not So Nice</address>
    </property>
</properties>';

$length = strlen('<property>');

while ($pos = strpos($xml, '<property>')) {
    $xml = substr_replace($xml, '<property upid=' . uniqid() . '>', $pos, $length);
    usleep(10); // Necessary so uniqid() is unique every iteration, it's kind of a hack not sure if it's the best solution
}

var_dump($xml);
Ermac
  • 1,181
  • 1
  • 8
  • 12
  • Are we treating XMLs as text string? Reconsider using DOM methods. – Parfait Apr 06 '18 at 19:09
  • XML is a structured, markup file that adheres to [W3C standards](https://www.w3.org/TR/xml/). It can contain [entity references](https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references), unicode, and binary data that may be hard to consume or needs to be escaped with string functions. While this example looks simple, OP omitted actual content. – Parfait Apr 06 '18 at 19:38
  • The XML feed that I've got to work with contains more than 4,000 properties, each with their own children. I'm afraid I don't follow DOM. I did have a look, but I'm brand new to using PHP with XML. In short, The answers above add the ID to the static XML content, but I want to be able to do this on the fly using a URL. Someone suggested cURL, but I don't know how I can get the XML URL into a string like the posts above. – Dave Pearce Apr 06 '18 at 19:52