DOMNode::C14N

(PHP 5 >= 5.2.0, PHP 7, PHP 8)

DOMNode::C14N将节点规范化为字符串

描述

public DOMNode::C14N(
    bool $exclusive = false,
    bool $withComments = false,
    ?array $xpath = null,
    ?array $nsPrefixes = null
): string|false

将节点规范化为字符串

参数

exclusive

启用仅对由提供的 xpath 或命名空间前缀匹配的节点进行排他解析。

withComments

在输出中保留注释。

xpath

一个 XPath 数组,用于按它们过滤节点。此数组中的每个条目都是一个关联数组,其中包含

  • 一个必需的 query 键,其中包含 XPath 表达式作为字符串。
  • 一个可选的 namespaces 键,其中包含一个数组,该数组将命名空间前缀(键)映射到命名空间 URI(值)。

nsPrefixes

一个用于按它们过滤节点的命名空间前缀数组。

返回值

返回规范化的节点作为字符串,或在失败时返回 false

示例

示例 #1 带 XPath 查询的示例

此示例演示了通过 XPath 查询规范化和过滤节点的更高级用法。

<?php

$dom
= new DOMDocument();
$dom->loadXML(<<<XML
<root xmlns:food="urn:food">
<!-- 冗余的命名空间声明将被规范化 -->
<food:fruit xmlns:food="urn:food">Apple</food:fruit>
<food:fruit>Orange</food:fruit>
<food:fruit>Pear</food:fruit>
<!-- 这里有蔬菜 -->
<food:vegetable>Lettuce</food:vegetable>
</root>
XML);

echo
$dom->C14N(true, false, [
"query" => ".//f:fruit|.//f:fruit/text()",
"namespaces" => ["f" => "urn:food"],
]);
?>

上面的示例将输出

<food:fruit>Apple</food:fruit><food:fruit>Orange</food:fruit><food:fruit>Pear</food:fruit>

参见

添加笔记

用户贡献的笔记 3 笔记

Rijk
11 年前
在处理 (格式错误的) HTML 时,您可能最好使用 DOMDocument 的 saveHTML() 方法。C14N() 将尝试使您的 HTML 成为有效的 XML,例如通过将 <br> 转换为 <br></br>。

因此,不要使用
$html = $Node->C14N();

使用
$html = $Node->ownerDocument->saveHTML( $Node );
jorda at edpsciences dot org
9 年前
如果节点未包含在文档树中,则 C14N() 返回空字符串
<?php
$d
= new DOMDocument('1.0');
$d->loadXML('<foo></foo>');
$n = $d->createElement('bar');
var_dump($n->C14N());
$d->documentElement->appendChild($n);
var_dump($n->C14N());
?>
output
string(0) ""
string(11) "<bar></bar>"
lordbaco
8 年前
[由 nielsdos 编辑:此问题已在 PHP 8.4 及更高版本中得到修复]

了解一下

<< 由于 PHP 中 XML 规范化存在已知问题,因此在 SimpleSAMLphp 中处理大型元数据文件会消耗大量资源,并且该量会随着元数据集中实体数量的平方而增加 >>
https://simplesamlphp.org/metaprocessing

<< C14N() 函数的运行时间似乎是 O(N^2)(或可能更糟?),具体取决于输入大小,这意味着随着输入的增长,它会变得非常慢。例如,一个包含大约 196000 个节点的输入大约需要 290 秒,而一个包含 486000 个节点的输入需要 2200 秒。>>
https://bugs.php.net/bug.php?id=53655

我们在 4.1 MB XML(105k 行)中遇到了相同的问题。票证 #53655 的示例代码需要 1 小时 36 分钟才能规范化它!
To Top