📄 xml.java
字号:
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * The contents of this file are subject to the Netscape 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/NPL/ * * 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 Netscape are * Copyright (C) 1997-2000 Netscape Communications Corporation. 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 Public License (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 NPL, indicate your decision by * deleting the provisions above and replace 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 NPL or the GPL. */package org.mozilla.javascript.xmlimpl;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 { 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(); 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) { if (cursor.isText()) return cursor.getChars(); if (cursor.isFinish()) return ""; cursor.push(); boolean wanRawText = cursor.isStartdoc() && !cursor.toFirstChild(); cursor.pop(); return wanRawText ? cursor.getTextValue() : cursor.xmlText( opts ); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -