【问题标题】:Remove attributes from xml nodes从 xml 节点中删除属性
【发布时间】:2015-03-07 15:17:46
【问题描述】:

我有一个这样的 RDF+XML 文档:

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

在 Symfony2 框架中使用 SimpleXMLElement 生成,代码如下:

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

谁能帮我删除节点 void:linkset 中的 xmlns:void 和 xmlns:rdf 属性(命名空间),以及 rdfs:comment 节点中的 xmlns:rdfs 属性(命名空间)?

我知道

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

但这会从根节点 rdf:RDF 中删除我不想要的 xmlns 命名空间。

如何解决?

【问题讨论】:

    标签: php xml


    【解决方案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 库自动完成的,该属性要求您明确指定它,因为该属性具有命名空间(第三个参数)属性不是元素,因此它们不会在那里共享任何命名空间;比较 Attributes and XML namespaces)。

    【讨论】:

    • 非常感谢您的澄清!您的建议 $voidNsUri = "rdfs.org/ns/void#"; $linksetNode = $rootNode->addChild('linkset', '', $voidNsUri);是我想要的,但正如你所说,这是无效的。您提供的示例不适合我,因为节点需要具有前缀“void”和“rdfs”。再次感谢。
    • 节点不需要有前缀。节点只需要在正确的命名空间中。前缀不是(总是)必要的。在给出的示例中,节点位于正确的命名空间中,即使它们没有(您预期但不是必需的)前缀。
    • 现在我明白了。 hakre 谢谢你的解释,我希望你的 cmets 也能帮助别人。
    猜你喜欢
    • 1970-01-01
    • 2016-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 2023-03-08
    相关资源
    最近更新 更多