Удалить атрибуты из узлов xml

0

У меня есть XML-документ RDF + следующим образом:

<?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>

сгенерированный с помощью SimpleXMLElement в платформе Symfony2 со следующим кодом:

        $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');

Может ли кто-нибудь помочь мне удалить xmlns: void и xmlns: rdf атрибуты (пространства имен) из узла void: linkset и xmlns: rdfs attribute (namespace) из rdfs: узел комментариев?

Я знаю

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

но это удалит пространство имен xmlns из корневого узла rdf: RDF, чего я не хочу.

Как это решить?

Теги:

1 ответ

1
Лучший ответ

Я предполагаю, что вы немного путаете пространства имен XML здесь, но я надеюсь, что смогу прояснить это для вас.

Атрибут xmlns:void="void" добавляется, потому что вы командуете simplexml, чтобы сделать это здесь:

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

Вы добавляете элемент void:linkset с префиксом (" void: " в начале первого параметра) и предоставляя новый (недопустимый) URI пространства имен (третий параметр " void "), поэтому simplexml создает для него новое объявление пространства имен ( недействительный) URI:

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

Он должен сделать это, потому что префикс " void: " был присвоен URI " http://rdfs.org/ns/void# ", а поскольку префикс void имеет другое значение пространства имен, его нужно переопределить. Это переопределение - это атрибут, который вам не нравится.

Таким образом, это можно решить, добавив элемент в существующее пространство имен:

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

Это приводит к тому, что элемент не требует переопределения префикса пространства имен к новому (недопустимому) URI:

<void:linkset>

Превращение этого в полноценный пример может привести к следующему:

$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]);

Примерный выход:

<?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>

Как вы можете видеть, все элементы правильно названы и находятся в соответствующем пространстве имен. Определения пространства имен размещаются там, где лучше всего подходят (это делается автоматически с помощью библиотеки XML, для этого атрибута требуется явно указать его, поскольку этот атрибут имеет пространство имен (третий параметр), а атрибуты не являются дочерними элементами элемента, поэтому они не разделяют любое пространство имен, сравнить атрибуты и пространства имен XML).

  • 0
    Большое спасибо за разъяснения! Ваше предложение $ voidNsUri = " rdfs.org/ns/void# "; $ linksetNode = $ rootNode-> addChild ('linkset', '', $ voidNsUri); это то, что я хочу, но, как вы говорите, это недействительно. Приведенный вами пример мне не подходит, потому что узлы должны иметь префикс "void" и "rdfs". Еще раз спасибо.
  • 1
    узлы не должны иметь префикс. узлы просто должны быть в правильном пространстве имен. префикс не (всегда) необходим для этого. В приведенном примере узлы находятся в правильном пространстве имен, даже если у них нет префикса (ожидаемого, но не обязательного).
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню