0

Suppose I have 3 XML files, like so:

dog.xml:

<animal> <species>dog</species> <weight>10</weight> <length>2</length> </animal> 

cat.xml:

<animal> <species>cat</species> <weight>2.5</weight> <length>1</length> </animal> 

rabbit.xml:

<animal> <species>rabbit</species> <weight>0.6</weight> <length>0.3</length> </animal> 

I'm attempting to combine these 3 into one PHP file that can be served as a webpage in .xml format, like so:

http://www.some.web.address.com/animals.php

<?xml version="1.0"?> <animals> <animal> <species>dog</species> <weight>10</weight> <length>2</length> </animal> <animal> <species>cat</species> <weight>2.5</weight> <length>1</length> </animal> <animal> <species>rabbit</species> <weight>0.6</weight> <length>0.3</length> </animal> </animals> 

The following stipulations apply:
-there should be a single xml version tag at the top, but no other xml version tags should be added elsewhere in the file
-the .xml tag formatting must be showing
-proper xml indenting should be maintained throughout

So far, this is the best way I can come up with, which is not that great:

<?php $dogXml = simplexml_load_file("/some/file/location/dog.xml"); $catXml = simplexml_load_file("/some/file/location/cat.xml"); $rabbitXml = simplexml_load_file("/some/file/location/rabbit.xml"); echo "<pre>"; echo htmlspecialchars('<?xml version="1.0"?>'); echo "<br>"; echo htmlspecialchars("<animals>"); echo "<br>"; echo htmlspecialchars(explode("\n", $dogXml->asXML(), 2)[1]); echo htmlspecialchars(explode("\n", $catXml->asXML(), 2)[1]); echo htmlspecialchars(explode("\n", $rabbitXml->asXML(), 2)[1]); echo htmlspecialchars("</animals>"); echo "</pre>"; ?> 

This produces the following output:

<?xml version="1.0"?> <animals> <animal> <species>dog</species> <weight>10</weight> <length>2</length> </animal> <animal> <species>cat</species> <weight>2.5</weight> <length>1</length> </animal> <animal> <species>rabbit</species> <weight>0.6</weight> <length>0.3</length> </animal> </animals> 

Which is correct, except for not preserving the indenting properly (the 3 animals and their descriptions should all be indented one more tab over).

Additionally, the

explode("\n", $dogXml->asXML(), 2)[1] 

trickery to suppress re-printing the xml version tag with each animal seems like it may not work in all cases.

Is there a better way to accomplish this? The best sources I could find on the subject are these posts:

remove xml version tag when a xml is created in php

Merge XML files in PHP

But each of the solutions in these posts either crashed with an error, did not preserve the xml tags, or added other content (ex. repeating the xml version tag). The only content I could get to work from these posts was the explode() call above.

Suggestions?

1
  • try this echo "\t" . htmlspecialchars("<animals>"); and echo "\t" .htmlspecialchars("</animals>"); "\t" = tab Commented Feb 19, 2018 at 17:50

1 Answer 1

1

Using DOMDocument rather than SimpleXML allows you to do it very easily...

function mergeFile ( DOMDocument $target, $fileName ) { $source = new DOMDocument(); $target->preserveWhiteSpace = false; $source->load($fileName); $import = $target->importNode($source->documentElement, true); $target->documentElement->appendChild($import); } $target = new DOMDocument(); $target->formatOutput = true; $target->preserveWhiteSpace = true; $target->loadXML('<?xml version="1.0" encoding="utf-8"?><animals></animals>'); mergeFile($target, "dog.xml"); mergeFile($target, "cat.xml"); mergeFile($target, "rabbit.xml"); $target->loadXML($target->saveXML()); $target->save("animals.xml"); 

There are a few fiddles in there to ensure the format is correct, at the end it re-loads the document to create the proper layout. Also when loading the sub-documents, the spacing isn't preserved to allow the main document to sort this out.

The output file is...

<?xml version="1.0" encoding="utf-8"?> <animals> <animal> <species>dog</species> <weight>10</weight> <length>2</length> </animal> <animal> <species>rabbit</species> <weight>0.6</weight> <length>0.3</length> </animal> <animal> <species>cat</species> <weight>2.5</weight> <length>1</length> </animal> </animals> 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.