Signatur
Beschreibung
hasAttributes() gibt true zurück, wenn ein Knoten mindestens ein Attribut hat, sonst false. In DOM Level 3 war die Methode auf Node definiert. Deshalb wurde sie früher auch von ProcessingInstruction geerbt, also von Knoten wie <?xml-stylesheet href="style.css" type="text/css"?>.
Eine ProcessingInstruction hat aber nie echte DOM-Attribute. Angaben wie href="…" in einer Verarbeitungsanweisung sind nur Pseudo-Attribute. Sie stehen als gewöhnlicher Text in der Eigenschaft data. Wo die Methode existierte, lieferte sie deshalb immer false.
Im aktuellen DOM Living Standard gibt es hasAttributes() nur noch auf Element. ProcessingInstruction erbt von CharacterData und damit von Node, aber nicht von Element. In modernen Browsern ist pi.hasAttributes daher undefined, und ein Aufruf löst einen TypeError aus. Wenn du wissen willst, welche Pseudo-Attribute eine Verarbeitungsanweisung hat, musst du data selbst auswerten.
Rückgabewert
false, weil Verarbeitungsanweisungen keine echten Attribute haben. In aktuellen Browsern gibt es die Methode nicht; ein Aufruf löst einen TypeError aus.Beispiele
Prüfen, ob die Methode vorhanden ist
const xml = '<?xml-stylesheet href="style.css" type="text/css"?><root/>';
const doc = new DOMParser().parseFromString(xml, 'application/xml');
const pi = doc.firstChild;
console.log(pi.nodeType === Node.PROCESSING_INSTRUCTION_NODE); // true
console.log(typeof pi.hasAttributes); // in modernen Browsern 'undefined'
// Sicherer Aufruf mit Fallback
const hasAttrs = typeof pi.hasAttributes === 'function' ? pi.hasAttributes() : false;
console.log(hasAttrs);
Pseudo-Attribute aus data auslesen
const xml = '<?xml-stylesheet href="style.css" type="text/css"?><root/>';
const doc = new DOMParser().parseFromString(xml, 'application/xml');
const pi = doc.firstChild;
const parsePseudoAttributes = (data) =>
Object.fromEntries(
[...data.matchAll(/([\w:-]+)\s*=\s*(["'])(.*?)\2/g)].map(([, name, , value]) => [name, value])
);
const attrs = parsePseudoAttributes(pi.data);
console.log(pi.target, attrs);
console.log('Hat Pseudo-Attribute:', Object.keys(attrs).length > 0);
Knotenübergreifende Hilfsfunktion statt Node.hasAttributes()
// Funktioniert für jede Knotenart, z. B. beim Durchlaufen eines XML-Baums
const nodeHasAttributes = (node) =>
node instanceof Element ? node.hasAttributes() : false;
const doc = new DOMParser().parseFromString(
'<?app mode="debug"?><root id="r"><!-- Kommentar --></root>',
'application/xml'
);
for (const node of [doc.firstChild, doc.documentElement, doc.documentElement.firstChild]) {
console.log(node.nodeName, nodeHasAttributes(node));
}
// Wichtig · Fallstricke
- Nicht standardkonform: Der DOM Living Standard definiert
hasAttributes()nur aufElement. Firefox hat die Methode mit Version 35 vonNodeaufElementverschoben. Auch Chrome, Safari und Edge bieten sie aufProcessingInstructionnicht an. Ein direkter Aufruf führt zuTypeError: pi.hasAttributes is not a function. - Pseudo-Attribute sind keine Attribute:
hrefodertypein<?xml-stylesheet …?>tauchen weder inattributesnoch beigetAttribute()auf. Sie stehen nur als Text indata. - Selbst auswerten ist eine Annäherung: Ein regulärer Ausdruck über
datadeckt die üblichen Fälle ab. Er prüft aber nicht streng nach der W3C-Empfehlung „Associating Style Sheets with XML documents“. Werte aus fremden Dokumenten solltest du nicht ungeprüft weiterverwenden, etwa als URL oder ininnerHTML. - In HTML-Dokumenten macht der Parser aus
<?…?>einen Kommentar und keine Verarbeitungsanweisung. Verarbeitungsanweisungen gibt es praktisch nur in XML-Dokumenten, etwa überDOMParsermitapplication/xml.