简体   繁体   中英

Remove attributes from xml nodes

I have an RDF+XML document like this:

<?xml version="1.0"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:void="http://rdfs.org/ns/void#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
<void:linkset xmlns:void="void" xmlns:rdf="rdf" rdf:about="http://xxxxx/aa.rdf#1">
<void:subjectsTarget>a</void:subjectsTarget> 
<void:objectsTarget>b</void:objectsTarget>
<void:linkPredicate>c</void:linkPredicate>
<rdfs:comment xmlns:rdfs="rdfs"> comment... </rdfs:comment>
</void:linkset>
</rdf:RDF>

generated with SimpleXMLElement in Symfony2 framework with following code:

        $rootNode = new \SimpleXMLElement('<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:void="http://rdfs.org/ns/void#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" />');
        $about = 'http://xxxx/aa.rdf#a';
        $linksetNode = $rootNode->addChild('void:linkset','','void');
        $linksetNode->addAttribute("rdf:about",$about,"rdf");
        $linksetNode->addChild('void:subjectsTarget','a','void');
        $linksetNode->addChild('void:objectsTarget','b','void');
        $linksetNode->addChild('void:linkPredicate','c','void');            
        $linksetNode->addChild('rdfs:comment','comment...','rdfs');

Can anyone help me to remove xmlns:void and xmlns:rdf attributes (namespaces) from node void:linkset, and xmlns:rdfs attribute (namespace) from rdfs:comment node?

I know for

$string = preg_replace('/xmlns:.*\"/','',$string);

but that will remove xmlns namespace from root node rdf:RDF what I don't want.

How to solve this?

I assume you're confusing a bit the XML namespaces here, but I hopefully be able to clarify this for you.

The xmlns:void="void" attribute is added because you're commanding simplexml to do so here:

$linksetNode = $rootNode->addChild('void:linkset', '', 'void');

You add the void:linkset element with the prefix (" void: " at the beginning of the first parameter) and providing a new (invalid) namespace URI (the third parameter " void ") therefore simplexml creates a new namespace declaration to that (invalid) URI:

<void:linkset xmlns:void="void"/>

It has to do so, because the " void: " prefix was assigned to the URI " http://rdfs.org/ns/void# ", and as the void prefix has a different namespace meaning, it has to be redefined. That re-definition is the attribute you don't like to be there.

So this can be solved by adding the element in the existing namespace:

$voidNsUri = "http://rdfs.org/ns/void#";
$linksetNode = $rootNode->addChild('linkset', '', $voidNsUri);

Which then results in the element w/o the need to redefine the namespace prefix to a new (invalid) URI:

<void:linkset>

Turning this into a fully fledged example could turn out the following:

$ns = [
    'rdf'  => "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
    'void' => 'http://rdfs.org/ns/void#',
    'rdfs' => 'http://www.w3.org/2000/01/rdf-schema#',
];

$about = 'http://xxxx/aa.rdf#a';

$buffer  = '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" />';
$xml     = new \SimpleXMLElement($buffer);
$linkset = $xml->addChild('linkset', '', $ns['void']);
$linkset->addAttribute("rdf:about", $about, $ns['rdf']);
$linkset->addChild('subjectsTarget', 'a', $ns['void']);
$linkset->addChild('objectsTarget', 'b', $ns['void']);
$linkset->addChild('linkPredicate', 'c', $ns['void']);
$linkset->addChild('comment', 'comment...', $ns['rdfs']);

echo tidy_repair_string($xml->asXML(), ['input-xml' => 1, 'indent' => 1, 'wrap' => 0]);

The exemplary outout:

<?xml version="1.0"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  <linkset xmlns="http://rdfs.org/ns/void#" rdf:about="http://xxxx/aa.rdf#a">
    <subjectsTarget>a</subjectsTarget>
    <objectsTarget>b</objectsTarget>
    <linkPredicate>c</linkPredicate>
    <comment xmlns="http://www.w3.org/2000/01/rdf-schema#">comment...</comment>
  </linkset>
</rdf:RDF>

As you can see, all the elements are correctly named and within the corresponding namespace. Namespace definitions are placed where see best fit (this is done automatically by the XML library, the attribute requires you to specify it explicitly because that attribute has a namespace (third parameter) and attributes are not children of the element so they don't share any namespace there; compare Attributes and XML namespaces ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM