(PHP)附加带有名称空间前缀的新XML子元素

时间:2014-12-10 13:51:43

标签: php xml namespaces prefix

我有一个XML,其中t:subscriptions元素包含多个t:subscription子元素。

我的主要目标是将当前t:subsciptions替换为全部t:subsciption元素或新t:subscription元素。目前我已经创建了新的$newsubs = ''; //new XML as string $sdom = new DOMDocument(); $sdom->loadXML($xml->asXML()); // current XML //dpm($sdom->saveXML()); $xpath = new DOMXPath($sdom); // ... x functions generate $newsubs string ... $remove = $sdom->getElementsByTagName('subscriptions')->item(0); // get t:subscriptions for removal $remove->parentNode->removeChild($remove); // remove t:subscriptions $fragment = $sdom->createDocumentFragment(); $fragment->appendXml($newsubs); $xpaths ->evaluate('//t:member') // this node holds t:subscriptions among others ->item(0) // there's always only one member node ->appendChild($fragment); debug($sdom->saveXML()); 元素作为字符串(没有掌握dom / simplexml类,所以我不得不使用“fallback”方法)。

现在我正在尝试通过simplexml_load_string然后使用dom_import_simplexml将字符串转换为XML,以便在XML中追加/替换当前订阅。我试过以下从这个网站上找到的例子:

Namespace prefix X on Y is not defined

我到目前为止只收到的错误是<t:myelement>asdasd</t:myelement>,这适用于所有元素。脚本删除名称空间前缀,尽管它们是在xml字符串中定义的,例如{{1}}。

将要添加此XML的XML文档已经添加了前缀。我不明白为什么它不能接受带前缀的XML并删除前缀,而新的XML会附加到文档中?没有意义。

1 个答案:

答案 0 :(得分:3)

错误消息可能意味着XML中缺少命名空间的“xmlns:*”属性,或者命名空间前缀未在XPath对象上注册。

XML文档

需要在双方定义命名空间。第一个是XML本身。

<foo xmlns="urn:foo"/>

<f:foo xmlns:f="urn:foo"/>

解析器将两者解析为相同的命名空间和本地名称。您可以将元素名称读为{urn:foo}:foo

以下是DOM上的几个* NS方法,允许您使用命名空间。命名空间始终是URN。前缀与匹配无关。

$node->getElementsByTagNameNS('urn:foo', 'foo')

仅在需要作为值时才提供前缀。例如,创建一个使用它的元素节点。

$document->createElementNS('urn:foo', 'foo'); // no prefix 
$document->createElementNS('urn:foo', 'f:foo'); // with prefix "f"

的XPath

XPath也使用表达式中的前缀。但它不应该从文件中读取它们。使用DOMXpath::registerNamespace()为特定命名空间注册自己的前缀。

实施例

您的问题缺少完整的XML,因此我将添加一个小的Atom示例。您可以看到XML和PHP中的命名空间是相同的,但前缀不同:

$xml = <<<'XML'
<?xml version="1.0" encoding="UTF-8"?>
<atom:feed xmlns:atom="http://www.w3.org/2005/Atom">
  <atom:title>Example Feed</atom:title>
  <atom:entry>
    <atom:title>Atom-Powered Robots Run Amok</atom:title>
    <atom:id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</atom:id>
  </atom:entry>
</atom:feed>
XML;

$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXPath($dom);
$xpath->registerNamespace('a', 'http://www.w3.org/2005/Atom');

var_dump($xpath->evaluate('string(//a:entry/a:title)'));

输出:

string(28) "Atom-Powered Robots Run Amok"