@@ -31,9 +31,12 @@ class DOMNode
3131{
3232 /**
3333 * @readonly
34- * @var DOMNamedNodeMap<DOMAttr>|null
34+ * @var DOMNamedNodeMap<DOMAttr<string> >|null
3535 */
3636 public $attributes;
37+
38+ /** @phpstan-assert-if-true !null $this->attributes */
39+ public function hasAttributes(): bool
3740}
3841
3942class DOMElement extends DOMNode
@@ -42,6 +45,13 @@ class DOMElement extends DOMNode
4245 /** @var DOMDocument */
4346 public $ownerDocument;
4447
48+ /**
49+ * @readonly
50+ * @inherited
51+ * @var DOMNamedNodeMap<DOMAttr<string>>|null
52+ */
53+ public $attributes;
54+
4555 /**
4656 * @param string $name
4757 * @return DOMNodeList<DOMElement>
@@ -55,6 +65,23 @@ class DOMElement extends DOMNode
5565 */
5666 public function getElementsByTagNameNS ($namespaceURI, $localName) {}
5767
68+ /**
69+ * @template T of string
70+ * @param T $qualifiedName
71+ * @return bool
72+ * @phpstan-assert-if-true (T is 'xml:id' ? DOMNameSpaceNode : DOMAttr<T>) $this->hasAttribute($qualifiedName)
73+ * @phpstan-assert-if-true DOMNameSpaceNode<DOMAttr<T>|DOMAttr<string>> $this->$attributes
74+ */
75+ public function hasAttribute(string $qualifiedName): bool
76+
77+ public function hasAttributeNS(?string $namespace, string $localName): bool
78+
79+ /**
80+ * @template T of string
81+ * @param T $qualifiedName
82+ * @return (T is 'xml:id' ? DOMNameSpaceNode|false : DOMAttr|false)
83+ */
84+ public function getAttributeNode(string $qualifiedName): DOMAttr<T>|DOMNameSpaceNode|false
5885}
5986
6087/**
@@ -86,12 +113,20 @@ class DOMXPath
86113
87114}
88115
116+ /**
117+ * @template Name as string
118+ */
89119class DOMAttr extends DOMNode
90120{
91-
92121 /** @var DOMDocument */
93122 public $ownerDocument;
94123
124+ /**
125+ * @var Name
126+ * @readonly
127+ */
128+ public $name;
129+
95130}
96131
97132class DOMCharacterData extends DOMNode
0 commit comments