我正在使用DOMDocument
类来读取一些XML,需要获取一个标签(DOMElement
实例)的属性名称和值,而不预先知道任何属性名称。文档并没有提供此类方法。文档中有介绍如何通过属性名称获取属性值,但我不知道属性名称和属性值,需要同时获取这两个信息。
我知道其他类似于SimpleXMLElement
的类可以实现此功能,但我更想知道如何使用DOMDocument
来做到。
我正在使用DOMDocument
类来读取一些XML,需要获取一个标签(DOMElement
实例)的属性名称和值,而不预先知道任何属性名称。文档并没有提供此类方法。文档中有介绍如何通过属性名称获取属性值,但我不知道属性名称和属性值,需要同时获取这两个信息。
我知道其他类似于SimpleXMLElement
的类可以实现此功能,但我更想知道如何使用DOMDocument
来做到。
$attributes = array();
foreach($element->attributes as $attribute_name => $attribute_node)
{
/** @var DOMNode $attribute_node */
$attributes[$attribute_name] = $attribute_node->nodeValue;
}
您可以使用DomNode->attributes属性获取给定DomNode的所有属性,它将返回包含属性名称和值的DOMNamedNodeMap。
foreach ($node->attributes as $attrName => $attrNode) {
// ...
}
我在搜索将节点属性转换为数组以便将该数组与数据库结果进行比较的方法时,偶然发现了这个问题。https://stackoverflow.com/users/264502/jan-molak 的答案确实解决了问题,但对于我的情况,它没有考虑到节点中可能缺少某些属性或者它们可能是空字符串,而从数据库返回的却是NULL
。
为了解决这个问题,我将其扩展成了下面的函数,希望对其他人有所帮助:
#Function to convert DOMNode into array with set of attributes, present in the node
#$null will replace empty strings with NULL, if set to true
#$extraAttributes will add any missing attributes as NULL or empty strings. Useful for standartization
public function attributesToArray(\DOMNode $node, bool $null = true, array $extraAttributes = []): array
{
$result = [];
#Iterrate attributes of the node
foreach ($node->attributes as $attrName => $attrValue) {
if ($null && $attrValue === '') {
#Add to resulting array as NULL, if it's empty string
$result[$attrName] = NULL;
} else {
#Add actual value
$result[$attrName] = $attrValue->textContent;
}
}
#Add any additional attributes, that are expected
if (!empty($extraAttributes)) {
foreach ($extraAttributes as $attribute) {
if (!isset($result[$attribute])) {
if ($null) {
#Add as NULL
$result[$attribute] = NULL;
} else {
#Or add as empty string
$result[$attribute] = '';
}
}
}
}
#Return resulting string
return $result;
}
}
我已将 nodeValue
替换为 textContent
,因为在谈论属性时,这种方式在我看来更加“自然”,但从技术上讲,在这里它们是相同的。
如果需要,此函数可作为 Simbiat/ArrayHelpers
的一部分在 Composer 中使用(https://github.com/Simbiat/ArrayHelpers)