Joel Bernstein, London Perl Mongers a href=mailtojoel@fysh.org by hcw25539

VIEWS: 12 PAGES: 13

									E4X: Primitive XML
 Joel Bernstein, London Perl Mongers
            joel@fysh.org
                 E4X?
• ECMAScript for XML
 • ECMAScript is the ISO Standard language
    known as JavaScript, JScript,
    ActionScript, ...
• Provides native XML support for JavaScript
 • inline XML literals in JavaScript code!
• Defined in ECMA-357, in use since FF 1.5
     What does it do?
• Adds native XML datatypes to JavaScript
• Extends semantics of operators to
  manipulate XML data
• Adds new operators for filtering, searching
  XML
• XML literals, namespaces, qualified names,
  etc
              XML DOM API
function
writeList
()
{


var
labels
=
xmlDoc.getElementsByTagName('label');


var
ol
=
document.createElement('OL');



for
(i=0;
i
<
labels.length;
i++)
{




var
li
=
document.createElement('LI');




for
(j=0;
j
<
labels[i].childNodes.length;
j++)
{






if
(labels[i].childNodes[j].nodeType
!=
ELEMENT_NODE)
{
continue;
}






var
cdata
=
document.createTextNode(








labels[i].childNodes[j].firstChild.nodeValue);






li.appendChild(cdata);




}




var
labelId
=
document.createTextNode('('
+






labels[i].getAttribute('id')
+
')');




li.appendChild(labelId);




ol.appendChild(li);


}


document.getElementById('updateTarget').appendChild(ol);
}
           E4X Equivalent
function
writeList
(domDoc)
{




var
xdoc
=

      new
XML((new
XMLSerializer())
        .serializeToString(domDoc.documentElement));




var
xlist
=
<ol/>;




for
each
(label
in
xdoc..label)









xlist.*
+=
<li>{
//
this
is
an
XMLList
object
          label.name.text()
+
'
('
+
label.@id
+
')'
        }</li>;




}




document.getElementById('updateTarget').innerHTML

      =
xlist;
//
UGH!
}
  No, what does it DO?
var
mongers
=
<perlmongers>
            <monger
gender=”male”
id=”2”>
              <contact
email=”joel@fysh.org”>
                <name>Joel
Bernstein</name>
                <age>27</age>
                <hair>Brown</hair>
              </contact>
            </monger>
            <monger
gender=”male”
id=”34”>
              <contact
email=”dave@dave.org.uk”>
                <name>Dave</name>
                <age>Unspecified</age>
                <hair>Corporate
Silver</hair>
              </contact>
            </monger>
          </perlmongers>;
 E4X syntax examples

• mongers..monger.
  (@id=="2").contact.name.text()

 •   Find all “item” elements at any depth, select one
     whose “id” attribute is ‘2’ and navigate to their
     name.
E4X syntax examples 2

• mongers..monger.
  (contact.@email=="joel@fysh.org")..na
  me.text()


 •   Similar to previous search, this time searching by
     child element attribute.
E4X syntax examples 3
• function
foo
()
{
return
<><item
/></
  item
/></>;
}

 • could
also
be:
return
new

     XMLList(<item
/>,
<item
/>);

• function
bar
()
{
var
x
=

  <items>{foo()}</items>;
return
x;
}

 •   Yields: <items><item /><item /></items>
            The good

• Terse, powerful syntax.
• Extends JS operators.
• Easy and natural to write, much less
  verbose than DOM
             The bad
• XML() and <xml>...</xml> objects are
  primitives rather than true objects
• Impedance mismatch between JS objects
  and XML objects -- a JS object can’t
  seamlessly render itself as XML
• Can’t directly insert E4X nodes into DOM
 • we can solve this last one
           E4X to DOM node
function
importNode
(
e4x,
doc
)
{


var
me



=
importNode,
xhtml,
domTree,
importMe;


me.Const

=
me.Const
||
{
mimeType:
'text/xml'
};


me.Static
=
me.Static
||
{};


me.Static.parser
=
me.Static.parser
||
new
DOMParser;


xhtml
=
<testing
xmlns="http://www.w3.org/1999/xhtml"
/>;


xhtml.test
=
e4x;


domTree
=
me.Static.parser.parseFromString(
xhtml.toXMLString(),
me.Const.mimeType
);


importMe
=
domTree.documentElement.firstChild;


while
(
importMe
&&
importMe.nodeType
!=
1
)
{




importMe
=
importMe.nextSibling;


}


if
(
!doc
)
doc
=
document;


return
importMe
?
doc.importNode(
importMe,
true
)
:
null;
}
function
appendTo
(
e4x,
node,
doc
)
{
//
inject
E4X
at
end
of
node


return
node.appendChild(
importNode(
e4x,
doc
||
node.ownerDocument
)
);
}

function
setContent
(
e4x,
node
)
{
//
replace
node
contents
with
E4X


while(
node.firstChild
)
{




node.removeChild(
node.firstChild
);


}


appendTo(
e4x,
node
);
}
 Thank you.
Any questions?

								
To top