How to get attributes with a namespace prefix in IE9 with mshtml?
We have a browser help object (BHO) written in C# that works just fine in IE8. However, accessing tags and attributes in a namespace开发者_JS百科 no longer works in IE9. For example, with
<p xmlns:acme="http://www.acme.com/2007/acme">
<input type="text" id="input1" value="" acme:initial="initial"/>
</p>
the following works in IE8:
IHTMLElement element = doc.getElementById("input1");
String initial = element.getAttribute("evsp:initial", 0) as String;
IE8 treats "acme:initial" as one text token whereas IE9 tries to be more namespace aware with "acme" as the namespace prefix.
Using getAttributeNS seems appropriate, but it does not seem to work:
IHTMLElement6 element6 = (IHTMLElement6)element;
String initial6 = (String)element6.getAttributeNS("http://www.acme.com/2007/acme",
"initial");
In the above, element6 is set to an mshtml.HTMLInputElementClass, but initial6 is null.
Since neither the old text-token nor namespace approach works, it looks like we're stuck.
It would also be fine to iterate through the actual attributes of an element, if attributes with a namespace prefix are included.
Is there a way with IE9 installed to get the value of a namespace-prefixed attribute?
Some details: The default PIA for Microsoft.mshtml.dll is version 7. IE9 uses mshtml.dll version 9. We use c:\C:\Windows\System32\mshtml.tlb (installed with IE9) to generate missing interfaces such as IHTMLElement6 and include these in our project. We have successfully used this technique in the past for other IE(N-1), IE(N) differences.
Here is a brute force approach, iterating all attributes:
// find your input element
IHTMLElement element = Doc3.getElementById("input1");
// get a collection of all attributes
IHTMLAttributeCollection attributes = (IHTMLAttributeCollection)((IHTMLDOMNode)Element).attributes;
// iterate all attributes
for (integer i = 0; i < attributes.length; i++)
{
IDispatch attribute = attributes.item(i);
// this eventually lists your attribute
System.Diagnostics.Debug.Writeln( ((IHTMLDOMAttribute) attribute).nodeName );
}
(Sorry for syntax errors, this came from my head.)
This treats your input element as raw DOM node and iterates its attributes. The drawback is: you get every attribute, not only the ones you see in HTML.
More simple
IHTMLElementCollection InputCollection = Doc3.getElementsByTagName("input1");
foreach (IHTMLInputElement InputTag in InputCollection) { Console.WriteLine(InputTag.name); }
精彩评论