Как обнаружить:
<?php
$d = new DOMDocument();
$d->loadXML('
<element>
<subelement xmlns:someprefix="http://mynamespace/asd">
</subelement>
</element>');
$sxe = simplexml_import_dom($d);
$namespaces = $sxe->getDocNamespaces(true);
$x = new DOMXpath($d);
foreach($namespaces as $prefix => $url){
$count = $x->evaluate("count(//*[namespace-uri()='".$url."' or @*[namespace-uri()='".$url."']])");
echo $prefix.' ( '.$url.' ): used '.$count.' times'.PHP_EOL;
}
Как удалить: pfff, о вашей единственной известной мне опции - это использовать xml_parse_into_struct()
(поскольку это не libxml2-зависимый afaik) и проходить через получившийся массив с функциями XML Writer
, пропуская объявления пространства имен не используется. Это не веселое времяпрепровождение, поэтому я оставлю реализацию вам. Другой вариант может быть XSL в соответствии с этим вопросом , но я сомневаюсь, что он очень полезен. Мое лучшее усилие, похоже, увенчалось успехом, но перемещает пространства имен «верхнего уровня» / rootnode детям, что приводит к еще большему беспорядку.
edit : это похоже на работу:
Учитывая XML (добавлен некоторый беспорядок в пространстве имен):
<element xmlns:yetanotherprefix="http://mynamespace/yet">
<subelement
xmlns:someprefix="http://mynamespace/foo"
xmlns:otherprefix="http://mynamespace/bar"
foo="bar"
yetanotherprefix:bax="foz">
<otherprefix:bar>
<yetanotherprefix:element/>
<otherprefix:element/>
</otherprefix:bar>
<otherprefix:bar>
<yetanotherprefix:element/>
<otherprefix:element/>
</otherprefix:bar>
<yetanotherprefix:baz/>
</subelement>
С xsl (namespaces & not()
предложением, основанным на предыдущем массиве $ used, так что вам все равно понадобится этот файл.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:yetanotherprefix="http://mynamespace/yet"
xmlns:otherprefix="http://mynamespace/bar">
<xsl:template match="/">
<xsl:apply-templates select="/*"/>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{name(.)}">
<xsl:apply-templates select="./@*"/>
<xsl:copy-of select="namespace::*[not(name()='someprefix')]"/>
<xsl:apply-templates select="./node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:copy/>
</xsl:template>
</xsl:stylesheet>
Результаты:
<?xml version="1.0"?>
<element xmlns:yetanotherprefix="http://mynamespace/yet">
<subelement xmlns:otherprefix="http://mynamespace/bar" foo="bar" yetanotherprefix:bax="foz">
<otherprefix:bar>
<yetanotherprefix:element/>
<otherprefix:element/>
</otherprefix:bar>
<otherprefix:bar>
<yetanotherprefix:element/>
<otherprefix:element/>
</otherprefix:bar>
<yetanotherprefix:baz/>
</subelement>
</element>