How can I select nodes from an object and then rel

2019-08-19 02:55发布

问题:

What I want to accomplish:

  • create an object by performing an XSL transformation (on an XML DOM object), let's call it 'fragment'
  • select some nodes by running an XPATH query on the resulting object
  • collect those nodes in, let's say, and array
  • append 'fragment' to a certain container in my HTML document
  • alter any one of those nodes, not by querying the DOM, but by referencing the said node like so: nodeCollection[x]

My motivation:

This is essentially a way of "caching" the objects that I know for sure I will have to alter later. So instead of walking the DOM to find them each time I need them, I want to "cache" them. It's much faster to select them with XPATH queries and once I do that I will no longer need to do any DOM traversing, which in my case can be rather slow (we're talking a lot of nodes here). I know this may generally come off as a very convoluted solution, but in my particular situation it pays off big time, at least in Firefox (see below).

How I did it in Firefox:

create a document fragment ('xml' and 'xsl' are XML DOM objects):

xsltProcessor=new XSLTProcessor();
xsltProcessor.importStylesheet(xsl);
fragment = xsltProcessor.transformToFragment(xml,document);

XPATH query:

var nodes = document.evaluate("//div", fragment.firstChild, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);

collect nodes in an array:

nodeCollection = new Array();
i = 0;
node = nodes.iterateNext();
while(node) {
nodeCollection[i] = node;
node = nodes.iterateNext();
i++;
}

append the fragment to a container in the HTML document:

document.getElementById("container").appendChild(fragment);

alter a node in the collection:

nodeCollection[0].style.border = '1px solid red';

.. and it works as intended.

The problems I ran into in Internet Explorer:

I used

var fragmentObject = new ActiveXObject("Msxml2.DOMDocument.3.0");
xml.transformNodeToObject(xsl,fragmentObject);

to create an object on which I can perform XPATH queries like so:

var nodes = fragmentObject.selectNodes("//div");

, but after this step I don't know how to append 'fragmentObject' to my container in the HTML document and then select individual nodes from 'nodes' and manipulate them like I did on Firefox.

What I think went wrong:

'fragmentObject' is a "Msxml2.DOMDocument.3.0", which is entirely different than a document fragment, so I can't just move nodes from it to my HTML document. If I try something like

container.appendChild(nodes[1]);

I get this error: "SCRIPT5022: DOM Exception: HIERARCHY_REQUEST_ERR (3)", which is what usually happens when trying to insert a node where it doesn't belong (or at least that's the explanation I found for this particular error).

Maybe there's some type of object that I`m unaware of that supports XPATH queries and can be appended to the HTML document (?)

回答1:

Instead of Msxml2.DOMDocument.3.0 try Microsoft.XMLDOM



回答2:

if you are adding the node, then as you said it must be in DOM range. like document.appendChild() will give the error. So we always do document.body.append.. Similarly, check if this container can directly add the Element..