使用PHP从XML中删除命名空间

I have an XML document that looks like this:

<Data 
  xmlns="http://www.domain.com/schema/data" 
  xmlns:dmd="http://www.domain.com/schema/data-metadata"
>
  <Something>...</Something>
</Data>

I am parsing the information using SimpleXML in PHP. I am dealing with arrays and I seem to be having a problem with the namespace.

My question is: How do I remove those namespaces? I read the data from an XML file.

Thank you!

php
dongliyu3278
dongliyu3278 如果您需要详细信息...我的原始问题已在此处发布,用户已经回复了(谢谢!)。但我发现命名空间导致他的循环不能运行并返回一个空数组。原始问题位于:stackoverflow.com/questions/1209301/...
大约 11 年之前 回复

4个回答

If you're using XPath then it's a limitation with XPath and not PHP look at this explanation on xpath and default namespaces for more info.

More specifically its the xmlns="" attribute in the root node which is causing the problem. This means that you'll need to register the namespace then use a QName thereafter to refer to elements.

$feed = simplexml_load_file('http://www.sitepoint.com/recent.rdf');
$feed->registerXPathNamespace("a", "http://www.domain.com/schema/data");
$result = $feed->xpath("a:Data/a:Something/...");

Important: The URI used in the registerXPathNamespace call must be identical to the one that is used in the actual XML file.

doulu4233
doulu4233 请注意重要部分。 我第一次看到这个答案时就错过了。
3 年多之前 回复
dqq22391
dqq22391 不幸的是,这似乎是唯一的方法。
接近 11 年之前 回复
dongyong6428
dongyong6428 是的,所以不要删除...我只是注册命名空间。 这解决了我的问题! 你是男人! 谢谢!
大约 11 年之前 回复

The following PHP code automatically detects the default namespace specified in the XML file under the alias "default". No all xpath queries have to be updated to include the prefix default:

So if you want to read XML files rather they contain an default NS definition or they don't and you want to query all Something elements, you could use the following code:

$xml = simplexml_load_file($name);
$namespaces = $xml->getDocNamespaces();
if (isset($namespaces[''])) {
    $defaultNamespaceUrl = $namespaces[''];
    $xml->registerXPathNamespace('default', $defaultNamespaceUrl);
    $nsprefix = 'default:';
} else {
    $nsprefix = '';
}

$somethings = $xml->xpath('//'.$nsprefix.'Something');

echo count($somethings).' times found';

I found the answer above to be helpful, but it didn't quite work for me. This ended up working better:

// Gets rid of all namespace definitions 
$xml_string = preg_replace('/xmlns[^=]*="[^"]*"/i', '', $xml_string);

// Gets rid of all namespace references
$xml_string = preg_replace('/[a-zA-Z]+:([a-zA-Z]+[=>])/', '$1', $xml_string);
dqq48152418
dqq48152418 几乎完美。 需要在节点名称后查找潜在空间。 如果节点内容有冒号<node> Order:Num </ node>,则也会删除节点内容,也找不到数字键<ns:addr2> Content </ ns:addr2>。 尝试:$ xml_string = preg_replace('/(<\ / | <)[a-zA-Z] + :( [a-zA-Z0-9] + [=>])/','$ 1 $ 2',$ xml_string);
大约一年之前 回复
douan8473
douan8473 在我生命中的少数几次之一,我提出了一个使用正则表达式操纵XML的解决方案。 我真的不想注册默认命名空间,并且不必要地混乱我的xpath查询。
接近 2 年之前 回复
doutan2456
doutan2456 我会用这样的东西摆脱“所有命名空间引用”:$ xml = preg_replace('/(<\ / *)[^>:] +:/','$ 1',$ xml);
大约 6 年之前 回复

To remove the namespace completely, you'll need to use Regular Expressions (RegEx). For example:

$feed = file_get_contents("http://www.sitepoint.com/recent.rdf");
$feed = preg_replace("/<.*(xmlns *= *[\"'].[^\"']*[\"']).[^>]*>/i", "", $feed); // This removes ALL default namespaces.
$xml_feed = simplexml_load_string($feed);

Then you've stripped any xml namespaces before you load the XML (be careful with the regex through, because if you have any fields with something like:

<![CDATA[ <Transfer xmlns="http://redeux.example.com">cool.</Transfer> ]]>

Then it will strip the xmlns from inside the CDATA which may lead to unexpected results.

doq70020
doq70020 很好,但它不会删除结束标记
7 年多之前 回复
dongmo6937
dongmo6937 -1因CDATA危险
接近 8 年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐