gpt4 book ai didi

php - 如何检测和删除不必要的 xmlns : attributes in PHP DOM?

转载 作者:行者123 更新时间:2023-12-04 16:52:06 25 4
gpt4 key购买 nike

假设我有一个这样的源文件:

<element>
<subelement xmlns:someprefix="mynamespace"/>
</element>
xmlns:someprefix显然这里不需要并且不做任何事情,因为该前缀没有在该元素中使用(或者在我的情况下,在文档中的任何地方)。

在 PHP 中,在我使用 DOMDocument->loadXML() 将它加载到 DOM 树后,我希望能够检测到这样的命名空间声明存在,并将其删除。

我知道我可以用 hasAttribute() 阅读它甚至用 removeAttributeNS() 删除它(奇怪)但前提是我知道它的前缀。它没有出现在 DOMNode->attributes根本没有,因为我试图找到的东西不被视为属性。除了将其序列化回 XML 字符串并运行正则表达式或其他东西之外,我看不到任何检测它是否存在的方法。

我该怎么做?有什么方法可以查询元素中声明了哪些命名空间(即 xmlns:something)?

最佳答案

如何检测:

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

如何删除:pff,我知道你唯一的选择是使用 xml_parse_into_struct() (因为这不是依赖于 libxml2 的 afaik),并使用 XML Writer 循环遍历结果数组函数,跳过未使用的命名空间声明。不是一个有趣的消遣,所以我会把实现留给你。根据 this question,另一种选择可能是 XSL ,但我怀疑它有多大用处。我的最大努力似乎成功了,但将“顶级”/rootnode 命名空间移至子节点,导致更加困惑。

编辑 :这似乎有效:

给定 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 数组,所以你仍然需要那个 afaik。
<?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>

关于php - 如何检测和删除不必要的 xmlns :<something> attributes in PHP DOM?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3810569/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com