Skip to content

Instantly share code, notes, and snippets.

@torus
Created April 17, 2010 00:49
Show Gist options
  • Save torus/369134 to your computer and use it in GitHub Desktop.
Save torus/369134 to your computer and use it in GitHub Desktop.
XML DOM construction utility & DOM matcher.
// -*- indent-tabs-mode: nil -*-
// Works on both WSH and Gecko
function E_ (name, attrs) {
var children = [];
for (var i = 2; i < arguments.length; i ++) {
children.push (arguments[i]);
}
return function (doc) {
var elem = doc.createElement (name);
if (attrs) {
for (var at in attrs) {
elem.setAttribute (at, attrs[at]);
}
for (var i = 0; i < children.length; i ++) {
var c = children[i];
var f = function (c) {
if (typeof (c) == "function") {
f (c (doc));
} else if (typeof (c) == "object" && c.tagName) { // Element
elem.appendChild (c);
} else if (typeof (c) == "object" && c.length != null) { // Array
for (var i = 0; i < c.length; i ++) {
f (c[i]);
}
} else {
var cont = doc.createTextNode (c);
elem.appendChild (cont);
}
}
f (c);
}
}
return elem;
}
}
function test_WSH () {
var doc = WScript.CreateObject ("MSXML.DOMDocument");
var content = E_ ("root", {abc: "1234"}, E_ ("hoge", {}, "text"));
doc.appendChild (content (doc));
WScript.echo (doc.xml);
}
//test_WSH ();
function xmlmatch_test_main () {
with (xmlmatch) {
var elem = E_ ("root", {},
E_ ("c1", {}, "cont c1"),
E_ ("c2", {}, "cont c2"),
E_ ("c3", {},
E_ ("c31", {}, "cont c31"),
E_ ("c32", {}, "cont c32"))) (document);
console.debug (elem);
var eat_root =
M ("root",
C (M ("c1", function (c) {console.assert (c.textContent == "cont c1"); return true}),
M ("c2"),
M ("c3", concat (M ("c31", function (c) {console.debug (c); return true;}),
M ("c32", function (c) {console.debug (c); return true;})))));
var ret = eat_root (elem);
console.debug ("done", ret);
}
}
xmlmatch = {};
xmlmatch.alter = function () {
var options = arguments;
return function (c) {
for (var i = 0; i < options.length; i ++) {
var p = options[i];
if (p (c)) {
return true;
}
}
return false;
};
};
xmlmatch.concat = function () {
var seq = arguments;
return function (elem) {
for (var c = elem.firstChild, i = 0; i < seq.length; c = c.nextSibling, i ++) {
if (! seq[i] (c))
return false;
}
return true;
};
};
xmlmatch.star = function (p) {
return function (elem) {
for (var c = elem.firstChild; c; c = c.nextSibling) {
if (! p (c))
return false;
}
return true;
}
};
xmlmatch.children = function () {
return xmlmatch.star (xmlmatch.alter.apply (this, arguments));
};
xmlmatch.matcher = function (tagname) {
var procs = arguments;
return function (e) {
if (e.tagName.toLowerCase () != tagname) {
// console.debug (e.tagName.toLowerCase (), "!=", tagname);
return false;
}
console.debug ("eating " + tagname);
for (var i = 1; i < procs.length; i ++) {
var p = procs[i];
if (p) {
var ret = p (e);
if (! ret)
return false;
}
}
return true;
}
};
xmlmatch.M = xmlmatch.matcher;
xmlmatch.C = xmlmatch.children;
<html>
<head>
<title>xml-match</title>
<script type="text/javascript" src="lazy_dom_construction.js"></script>
<script type="text/javascript" src="xml_match.js"></script>
</head>
<body>
<h1>xml-match</h1>
<script>xmlmatch_test_main ()</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment