3

i'm trying to add generate an output like this:

<mets ....
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.loc.gov/METS/       
http://www.loc.gov/standards/mets/mets.xsd">

I can generate everything fine, but cannot add the xmlns:xlink attribute. The closest I get is:

$this->xml = new SimpleXMLElement('<mets></mets>');
$mets->addAttribute("xlink:someName", "blabla", "http://www.w3.org/1999/xlink");    
$mets->addAttribute("xsi:schemaLocation", "http://www.loc.gov/METS/  
http://www.loc.gov/standards/mets/mets.xsd",
"http://www.w3.org/2001/XMLSchema-instance");

Generates:

<mets ....
xmlns:xlink="http://www.w3.org/1999/xlink"
----begin of part I don't desire-----
xlink:someName="blablabla"
----end of  part I don't desire-----
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.loc.gov/METS/       
http://www.loc.gov/standards/mets/mets.xsd">

How can I add xmlns:xlink without adding xlink:somethingElse?

hakre
  • 193,403
  • 52
  • 435
  • 836
  • 2
    if you need to have an xmlns:xlink attribute aren't you going to have xlink:something somewhere in your code anyway? isn't that the whole reason you need to define an xmlns:xlink attribute in the first place? – markasoftware Mar 01 '13 at 01:25
  • Yes i have to use xlink:href in a inner node. But I can make appear the xmlns:xlink in the root node and the xlink:href in that inner node – MariaEmilia Mar 02 '13 at 20:28
  • This looks like a workaround worth checking: http://stackoverflow.com/questions/6927567/adding-a-namespace-when-using-simplexmlelement – marty Mar 04 '13 at 19:51

1 Answers1

4

The solution I've come up with is rather straight forward:

Because

$mets->addAttribute("xlink:someName", "", "http://www.w3.org/1999/xlink");

will always add two attributes - one for the namespace declaration (xmlns:xlink) and then the attribute you actually add (xlink:someName) - all you need to do is then to remove the unwanted added attribute and the prefix namespace attribute will remain:

unset($mets->attributes('xlink', true)['someName']);

Full example:

$mets = new SimpleXMLElement('<mets></mets>');
$mets->addAttribute("xlink:someName", "", "http://www.w3.org/1999/xlink");
unset($mets->attributes('xlink', true)['someName']);
echo $mets->asXML();

Output:

<?xml version="1.0"?>
<mets xmlns:xlink="http://www.w3.org/1999/xlink"/>

However this normally should not be necessary. You either need to use the namespace for something - then simplexml will add it when needed - or you don't need it, then there is no need to add it.

XML itself has no requirement at all to declare a namespace which is not used. Therefore you likely can leave it out as well or you only need to add it where you need to add it, e.g. the specific xlink element / attribute later on.

Any XML parser that supports namespaces will support any well-formed XML+Namspaces document, so there should really be no reason to worry whether or not the root element has that declaration and with which prefix. Simplexml just takes care of that, just add the xlink attribute where you need it. Example:

$mets = new SimpleXMLElement('<mets></mets>');
$child = $mets->addChild('child');
$child->addAttribute('xlink:href', 'child.xml', 'http://www.w3.org/1999/xlink');
$child = $child->addChild('child');
$child->addAttribute('xlink:href', 'child.xml', 'http://www.w3.org/1999/xlink');
echo $mets->asXML();

Output:

<?xml version="1.0"?>
<mets>
  <child xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="child.xml">
    <child xlink:href="child.xml"/>
  </child>
</mets>
hakre
  • 193,403
  • 52
  • 435
  • 836