📄 xml.java
字号:
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Ethan Hugg * Terry Lucas * Milen Nankov * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */package org.mozilla.javascript.xml.impl.xmlbeans;import java.io.Serializable;import java.util.*;import org.mozilla.javascript.*;import org.apache.xmlbeans.XmlCursor;import org.apache.xmlbeans.XmlCursor.XmlBookmark;import org.apache.xmlbeans.XmlCursor.TokenType;import org.apache.xmlbeans.XmlException;import org.apache.xmlbeans.XmlObject;import org.apache.xmlbeans.XmlOptions;class XML extends XMLObjectImpl{ static final long serialVersionUID = -630969919086449092L; final static class XScriptAnnotation extends XmlBookmark implements Serializable { private static final long serialVersionUID = 1L; javax.xml.namespace.QName _name; XML _xScriptXML; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Constructurs // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// XScriptAnnotation (XmlCursor curs) { _name = curs.getName(); } } /** * */ final static class NamespaceDeclarations { private int _prefixIdx; private StringBuffer _namespaceDecls; private String _defaultNSURI; NamespaceDeclarations (XmlCursor curs) { _prefixIdx = 0; _namespaceDecls = new StringBuffer(); skipNonElements(curs); _defaultNSURI = curs.namespaceForPrefix(""); if (isAnyDefaultNamespace()) { addDecl("", _defaultNSURI); } } private void addDecl (String prefix, String ns) { _namespaceDecls.append((prefix.length() > 0 ? "declare namespace " + prefix : "default element namespace") + " = \"" + ns + "\"" + "\n"); } String getNextPrefix (String ns) { String prefix = "NS" + _prefixIdx++; _namespaceDecls.append("declare namespace " + prefix + " = " + "\"" + ns + "\"" + "\n"); return prefix; } boolean isAnyDefaultNamespace () { return _defaultNSURI != null ?_defaultNSURI.length() > 0 : false; } String getDeclarations() { return _namespaceDecls.toString(); } } // Fields //static final XML prototype = new XML(); private XScriptAnnotation _anno;//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Constructors // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * * @param anno */ private XML(XMLLibImpl lib, XScriptAnnotation anno) { super(lib, lib.xmlPrototype); _anno = anno; _anno._xScriptXML = this; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Public factories for creating a XScript XML object given an XBean cursor. // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static XML createEmptyXML(XMLLibImpl lib) { XScriptAnnotation anno; XmlObject xo = XmlObject.Factory.newInstance(); XmlCursor curs = xo.newCursor(); try { anno = new XScriptAnnotation(curs); curs.setBookmark(anno); } finally { curs.dispose(); } return new XML(lib, anno); } private static XML createXML (XMLLibImpl lib, XmlCursor curs) { if (curs.currentTokenType().isStartdoc()) { curs.toFirstContentToken(); } XScriptAnnotation anno = findAnnotation(curs); return new XML(lib, anno); } /** * Special constructor for making an attribute * */ private static XML createAttributeXML(XMLLibImpl lib, XmlCursor cursor) { if (!cursor.isAttr()) throw new IllegalArgumentException(); XScriptAnnotation anno = new XScriptAnnotation(cursor); cursor.setBookmark(anno); return new XML(lib, anno); } /** * * @param qname * @param value * @return */ static XML createTextElement(XMLLibImpl lib, javax.xml.namespace.QName qname, String value) { XScriptAnnotation anno; XmlObject xo = XmlObject.Factory.newInstance(); XmlCursor cursor = xo.newCursor(); try { cursor.toNextToken(); cursor.beginElement(qname.getLocalPart(), qname.getNamespaceURI()); //if(namespace.length() > 0) // cursor.insertNamespace("", namespace); cursor.insertChars(value); cursor.toStartDoc(); cursor.toNextToken(); anno = new XScriptAnnotation(cursor); cursor.setBookmark(anno); } finally { cursor.dispose(); } return new XML(lib, anno); } static XML createFromXmlObject(XMLLibImpl lib, XmlObject xo) { XScriptAnnotation anno; XmlCursor curs = xo.newCursor(); if (curs.currentTokenType().isStartdoc()) { curs.toFirstContentToken(); } try { anno = new XScriptAnnotation(curs); curs.setBookmark(anno); } finally { curs.dispose(); } return new XML(lib, anno); } static XML createFromJS(XMLLibImpl lib, Object inputObject) { XmlObject xo; boolean isText = false; String frag; if (inputObject == null || inputObject == Undefined.instance) { frag = ""; } else if (inputObject instanceof XMLObjectImpl) { // todo: faster way for XMLObjects? frag = ((XMLObjectImpl) inputObject).toXMLString(0); } else { if (inputObject instanceof Wrapper) { Object wrapped = ((Wrapper)inputObject).unwrap(); if (wrapped instanceof XmlObject) { return createFromXmlObject(lib, (XmlObject)wrapped); } } frag = ScriptRuntime.toString(inputObject); } if (frag.trim().startsWith("<>")) { throw ScriptRuntime.typeError("Invalid use of XML object anonymous tags <></>."); } if (frag.indexOf("<") == -1) { // Must be solo text node, wrap in XML fragment isText = true; frag = "<textFragment>" + frag + "</textFragment>"; } XmlOptions options = new XmlOptions(); if (lib.ignoreComments) { options.put(XmlOptions.LOAD_STRIP_COMMENTS); } if (lib.ignoreProcessingInstructions) { options.put(XmlOptions.LOAD_STRIP_PROCINSTS); } if (lib.ignoreWhitespace) { options.put(XmlOptions.LOAD_STRIP_WHITESPACE); } try { xo = XmlObject.Factory.parse(frag, options); // Apply the default namespace Context cx = Context.getCurrentContext(); String defaultURI = lib.getDefaultNamespaceURI(cx); if(defaultURI.length() > 0) { XmlCursor cursor = xo.newCursor(); boolean isRoot = true; while(!cursor.toNextToken().isEnddoc()) { if(!cursor.isStart()) continue; // Check if this element explicitly sets the // default namespace boolean defaultNSDeclared = false; cursor.push(); while(cursor.toNextToken().isAnyAttr()) { if(cursor.isNamespace()) { if(cursor.getName().getLocalPart().length() == 0) { defaultNSDeclared = true; break; } } } cursor.pop(); if(defaultNSDeclared) { cursor.toEndToken(); continue; } // Check if this element's name is in no namespace javax.xml.namespace.QName qname = cursor.getName(); if(qname.getNamespaceURI().length() == 0) { // Change the namespace qname = new javax.xml.namespace.QName(defaultURI, qname.getLocalPart()); cursor.setName(qname); } if(isRoot) { // Declare the default namespace cursor.push(); cursor.toNextToken(); cursor.insertNamespace("", defaultURI); cursor.pop(); isRoot = false; } } cursor.dispose(); } } catch (XmlException xe) {/*todo need to handle namespace prefix not found in XML look for namespace type in the scope change. String errorMsg = "Use of undefined namespace prefix: "; String msg = xe.getError().getMessage(); if (msg.startsWith(errorMsg)) { String prefix = msg.substring(errorMsg.length()); }*/ String errMsg = xe.getMessage(); if (errMsg.equals("error: Unexpected end of file after null")) { // Create an empty document. xo = XmlObject.Factory.newInstance(); } else { throw ScriptRuntime.typeError(xe.getMessage()); } } catch (Throwable e) { // todo: TLL Catch specific exceptions during parse. throw ScriptRuntime.typeError("Not Parsable as XML"); } XmlCursor curs = xo.newCursor(); if (curs.currentTokenType().isStartdoc()) { curs.toFirstContentToken(); } if (isText) { // Move it to point to the text node curs.toFirstContentToken(); } XScriptAnnotation anno; try { anno = new XScriptAnnotation(curs); curs.setBookmark(anno); } finally { curs.dispose(); } return new XML(lib, anno); } static XML getFromAnnotation(XMLLibImpl lib, XScriptAnnotation anno) { if (anno._xScriptXML == null) { anno._xScriptXML = new XML(lib, anno); } return anno._xScriptXML; }//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Private functions: // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * * @param curs * @return */ private static TokenType skipNonElements (XmlCursor curs) { TokenType tt = curs.currentTokenType(); while (tt.isComment() || tt.isProcinst()) { tt = curs.toNextToken(); } return tt; } /** * * @param curs * @return */ protected static XScriptAnnotation findAnnotation(XmlCursor curs) { XmlBookmark anno = curs.getBookmark(XScriptAnnotation.class); if (anno == null) { anno = new XScriptAnnotation(curs); curs.setBookmark(anno); } return (XScriptAnnotation)anno; } /** * * @return */ private XmlOptions getOptions() { XmlOptions options = new XmlOptions(); if (lib.ignoreComments) { options.put(XmlOptions.LOAD_STRIP_COMMENTS); } if (lib.ignoreProcessingInstructions) { options.put(XmlOptions.LOAD_STRIP_PROCINSTS); } if (lib.ignoreWhitespace) { options.put(XmlOptions.LOAD_STRIP_WHITESPACE); } if (lib.prettyPrinting) { options.put(XmlOptions.SAVE_PRETTY_PRINT, null); options.put(XmlOptions.SAVE_PRETTY_PRINT_INDENT, new Integer(lib.prettyIndent)); } return options; } /** * * @param cursor * @param opts * @return */ private static String dumpNode(XmlCursor cursor, XmlOptions opts) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -