final XML ecmaToXml(Object object) { // See ECMA357 10.3 if (object == null || object == Undefined.instance) { throw ScriptRuntime.typeError("Cannot convert " + object + " to XML"); } if (object instanceof XML) return (XML) object; if (object instanceof XMLList) { XMLList list = (XMLList) object; if (list.getXML() != null) { return list.getXML(); } else { throw ScriptRuntime.typeError("Cannot convert list of >1 element to XML"); } } // TODO Technically we should fail on anything except a String, Number or Boolean // See ECMA357 10.3 // Extension: if object is a DOM node, use that to construct the XML // object. if (object instanceof Wrapper) { object = ((Wrapper) object).unwrap(); } if (object instanceof org.w3c.dom.Node) { org.w3c.dom.Node node = (org.w3c.dom.Node) object; return newXML(XmlNode.createElementFromNode(node)); } // Instead we just blindly cast to a String and let them convert anything. String s = ScriptRuntime.toString(object); // TODO Could this get any uglier? if (s.length() > 0 && s.charAt(0) == '<') { return parse(s); } else { return newXML(XmlNode.createText(options, s)); } }
void removeNamespace(Namespace namespace) { Namespace current = getNodeNamespace(); // Do not remove in-use namespace if (namespace.is(current)) return; NamedNodeMap attrs = this.dom.getAttributes(); for (int i = 0; i < attrs.getLength(); i++) { XmlNode attr = XmlNode.createImpl(attrs.item(i)); if (namespace.is(attr.getNodeNamespace())) return; } // TODO I must confess I am not sure I understand the spec fully. See ECMA357 13.4.4.31 String existingPrefix = getExistingPrefixFor(namespace); if (existingPrefix != null) { if (namespace.isUnspecifiedPrefix()) { // we should remove any namespace with this URI from scope; we do this by declaring a // namespace with the same // prefix as the existing prefix and setting its URI to the default namespace declareNamespace(existingPrefix, getDefaultNamespace().getUri()); } else { if (existingPrefix.equals(namespace.getPrefix())) { declareNamespace(existingPrefix, getDefaultNamespace().getUri()); } } } else { // the argument namespace is not declared in this scope, so do nothing. } }
private static XmlNode createImpl(Node node) { if (node instanceof Document) throw new IllegalArgumentException(); XmlNode rv = null; if (getUserData(node) == null) { rv = new XmlNode(); rv.dom = node; setUserData(node, rv); } else { rv = getUserData(node); } return rv; }
private XML parse(String frag) { try { return newXML( XmlNode.createElement( options, getDefaultNamespaceURI(Context.getCurrentContext()), frag)); } catch (SAXException e) { throw ScriptRuntime.typeError("Cannot parse XML: " + e.getMessage()); } }
void addMatchingChildren(XMLList result, XmlNode.Filter filter) { Node node = this.dom; NodeList children = node.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { Node childnode = children.item(i); XmlNode child = XmlNode.createImpl(childnode); if (filter.accept(childnode)) { result.addToList(child); } } }
private void exportToScope(boolean sealed) { xmlPrototype = newXML(XmlNode.createText(options, "")); xmlListPrototype = newXMLList(); namespacePrototype = Namespace.create(this.globalScope, null, XmlNode.Namespace.GLOBAL); qnamePrototype = QName.create( this, this.globalScope, null, XmlNode.QName.create(XmlNode.Namespace.create(""), "")); xmlPrototype.exportAsJSClass(sealed); xmlListPrototype.exportAsJSClass(sealed); namespacePrototype.exportAsJSClass(sealed); qnamePrototype.exportAsJSClass(sealed); }
static XmlNode newElementWithText( XmlProcessor processor, XmlNode reference, XmlNode.QName qname, String value) { if (reference instanceof org.w3c.dom.Document) throw new IllegalArgumentException("Cannot use Document node as reference"); Document document = null; if (reference != null) { document = reference.dom.getOwnerDocument(); } else { document = processor.newDocument(); } Node referenceDom = (reference != null) ? reference.dom : null; Element e = document.createElementNS(qname.getUri(), qname.qualify(referenceDom)); if (value != null) { e.appendChild(document.createTextNode(value)); } return XmlNode.createImpl(e); }
/* TODO: Can this can be replaced by ecmaToXml below? */ final XML newXMLFromJs(Object inputObject) { String frag; if (inputObject == null || inputObject == Undefined.instance) { frag = ""; } else if (inputObject instanceof XMLObjectImpl) { // todo: faster way for XMLObjects? frag = ((XMLObjectImpl) inputObject).toXMLString(); } else { frag = ScriptRuntime.toString(inputObject); } if (frag.trim().startsWith("<>")) { throw ScriptRuntime.typeError("Invalid use of XML object anonymous tags <></>."); } if (frag.indexOf("<") == -1) { // Solo text node return newXML(XmlNode.createText(options, frag)); } return parse(frag); }
final XML newTextElementXML(XmlNode reference, XmlNode.QName qname, String value) { return newXML(XmlNode.newElementWithText(options, reference, qname, value)); }