xmlserializer.java

来自「JAVA 所有包」· Java 代码 · 共 1,471 行 · 第 1/4 页

JAVA
1,471
字号
                    if (value == null) {                        value=XMLSymbols.EMPTY_STRING;                    }                    if (value.equals(NamespaceContext.XMLNS_URI)) {                        if (fDOMErrorHandler != null) {                            String msg = DOMMessageFormatter.formatMessage(                                DOMMessageFormatter.XML_DOMAIN,"CantBindXMLNS",null );                            modifyDOMError(msg,  DOMError.SEVERITY_ERROR, null, attr);                            boolean continueProcess = fDOMErrorHandler.handleError(fDOMError);                            if (!continueProcess) {                                // stop the namespace fixup and validation            	                throw new RuntimeException(             	                    DOMMessageFormatter.formatMessage(            	                    DOMMessageFormatter.SERIALIZER_DOMAIN,            	                    "SerializationStopped", null));                            }                        }                    } else {                        prefix = attr.getPrefix();                        prefix = (prefix == null ||                                   prefix.length() == 0) ? XMLSymbols.EMPTY_STRING :fSymbolTable.addSymbol(prefix);                        String localpart = fSymbolTable.addSymbol( attr.getLocalName());                        if (prefix == XMLSymbols.PREFIX_XMLNS) { //xmlns:prefix                            value = fSymbolTable.addSymbol(value);                            // record valid decl                            if (value.length() != 0) {                                fNSBinder.declarePrefix(localpart, value);                            } else {                                // REVISIT: issue error on invalid declarations                                //          xmlns:foo = ""                            }                            continue;                        } else { // xmlns                            // empty prefix is always bound ("" or some string)                            value = fSymbolTable.addSymbol(value);                            fNSBinder.declarePrefix(XMLSymbols.EMPTY_STRING, value);                            continue;                        }                    }  // end-else: valid declaration                } // end-if: namespace declaration             }  // end-for            //-----------------------            // get element uri/prefix            //-----------------------            uri = elem.getNamespaceURI();                        prefix = elem.getPrefix();            //----------------------            // output element name            //----------------------            // REVISIT: this could be removed if we always convert empty string to null            //          for the namespaces.            if ((uri !=null && prefix !=null ) && uri.length() == 0 && prefix.length()!=0) {                // uri is an empty string and element has some prefix                // the namespace alg later will fix up the namespace attributes                // remove element prefix                 prefix = null;                 _printer.printText( '<' );                _printer.printText( elem.getLocalName() );                _printer.indent();            } else {                _printer.printText( '<' );                _printer.printText( tagName );                _printer.indent();            }            // ---------------------------------------------------------            // Fix up namespaces for element: per DOM L3             // Need to consider the following cases:            //            // case 1: <foo:elem xmlns:ns1="myURI" xmlns="default"/>             // Assume "foo", "ns1" are declared on the parent. We should not miss             // redeclaration for both "ns1" and default namespace. To solve this             // we add a local binder that stores declaration only for current element.            // This way we avoid outputing duplicate declarations for the same element            // as well as we are not omitting redeclarations.            //            // case 2: <elem xmlns="" xmlns="default"/>             // We need to bind default namespace to empty string, to be able to             // omit duplicate declarations for the same element            //            // case 3: <xsl:stylesheet xmlns:xsl="http://xsl">            // We create another element body bound to the "http://xsl" namespace            // as well as namespace attribute rebounding xsl to another namespace.            // <xsl:body xmlns:xsl="http://another">            // Need to make sure that the new namespace decl value is changed to             // "http://xsl"            //            // ---------------------------------------------------------            // check if prefix/namespace is correct for current element            // ---------------------------------------------------------            if (uri != null) {  // Element has a namespace                uri = fSymbolTable.addSymbol(uri);                prefix = (prefix == null ||                           prefix.length() == 0) ? XMLSymbols.EMPTY_STRING :fSymbolTable.addSymbol(prefix);                if (fNSBinder.getURI(prefix) == uri) {                    // The xmlns:prefix=namespace or xmlns="default" was declared at parent.                    // The binder always stores mapping of empty prefix to "".                    // (NOTE: local binder does not store this kind of binding!)                    // Thus the case where element was declared with uri="" (with or without a prefix)                    // will be covered here.                } else {                    // the prefix is either undeclared                     // or                    // conflict: the prefix is bound to another URI                    if (fNamespacePrefixes) {                        printNamespaceAttr(prefix, uri);                    }                    fLocalNSBinder.declarePrefix(prefix, uri);                    fNSBinder.declarePrefix(prefix, uri);                }            } else { // Element has no namespace                if (elem.getLocalName() == null) {                    //  DOM Level 1 node!                    if (fDOMErrorHandler != null) {                        String msg = DOMMessageFormatter.formatMessage(                            DOMMessageFormatter.DOM_DOMAIN, "NullLocalElementName",                             new Object[]{elem.getNodeName()});                        modifyDOMError(msg,DOMError.SEVERITY_ERROR, null, elem);                        boolean continueProcess = fDOMErrorHandler.handleError(fDOMError);                        // REVISIT: should we terminate upon request?                        if (!continueProcess) {                           throw new RuntimeException(             	               DOMMessageFormatter.formatMessage(            	               DOMMessageFormatter.SERIALIZER_DOMAIN,            	               "SerializationStopped", null));                        }                    }                } else { // uri=null and no colon (DOM L2 node)                    uri = fNSBinder.getURI(XMLSymbols.EMPTY_STRING);                    if (uri !=null && uri.length() > 0) {                        // there is a default namespace decl that is bound to                        // non-zero length uri, output xmlns=""                        if (fNamespacePrefixes) {                            printNamespaceAttr(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING);                        }                        fLocalNSBinder.declarePrefix(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING);                        fNSBinder.declarePrefix(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING);                    }                }            }            // -----------------------------------------            // Fix up namespaces for attributes: per DOM L3             // check if prefix/namespace is correct the attributes            // -----------------------------------------            for (i = 0; i < length; i++) {                attr = (Attr) attrMap.item( i );                value = attr.getValue();                name = attr.getNodeName();                                uri = attr.getNamespaceURI();                // Fix attribute that was declared with a prefix and namespace=""                if (uri !=null && uri.length() == 0) {                    uri=null;                    // we must remove prefix for this attribute                    name=attr.getLocalName();                }                if (DEBUG) {                    System.out.println("==>process attribute: "+attr.getNodeName());                }                // make sure that value is never null.                if (value == null) {                    value=XMLSymbols.EMPTY_STRING;                }                if (uri != null) {  // attribute has namespace !=null                    prefix = attr.getPrefix();                    prefix = prefix == null ? XMLSymbols.EMPTY_STRING :fSymbolTable.addSymbol(prefix);                    String localpart = fSymbolTable.addSymbol( attr.getLocalName());                    // ---------------------------------------------------                    // print namespace declarations namespace declarations                     // ---------------------------------------------------                    if (uri != null && uri.equals(NamespaceContext.XMLNS_URI)) {                        // check if we need to output this declaration                        prefix = attr.getPrefix();                        prefix = (prefix == null ||                                   prefix.length() == 0) ? XMLSymbols.EMPTY_STRING : fSymbolTable.addSymbol(prefix);                        localpart = fSymbolTable.addSymbol( attr.getLocalName());                        if (prefix == XMLSymbols.PREFIX_XMLNS) { //xmlns:prefix                            localUri = fLocalNSBinder.getURI(localpart);  // local prefix mapping                            value = fSymbolTable.addSymbol(value);                            if (value.length() != 0 ) {                                if (localUri == null) {                                    // declaration was not printed while fixing element namespace binding                                                                        // If the DOM Level 3 namespace-prefixes feature is set to false                                    // do not print xmlns attributes                                    if (fNamespacePrefixes) {                                        printNamespaceAttr(localpart, value);                                    }                                    	                                    // case 4: <elem xmlns:xx="foo" xx:attr=""/>                                    // where attribute is bound to "bar".                                     // If the xmlns:xx is output here first, later we should not                                    // redeclare "xx" prefix. Instead we would pick up different prefix                                    // for the attribute.                                    // final: <elem xmlns:xx="foo" NS1:attr="" xmlns:NS1="bar"/>                                    fLocalNSBinder.declarePrefix(localpart, value);                                }                            } else {                                // REVISIT: issue error on invalid declarations                                //          xmlns:foo = ""                            }                            continue;                        } else { // xmlns                            // empty prefix is always bound ("" or some string)                            uri = fNSBinder.getURI(XMLSymbols.EMPTY_STRING);                            localUri=fLocalNSBinder.getURI(XMLSymbols.EMPTY_STRING);                            value = fSymbolTable.addSymbol(value);                            if (localUri == null ){                                // declaration was not printed while fixing element namespace binding                                if (fNamespacePrefixes) {                                    printNamespaceAttr(XMLSymbols.EMPTY_STRING, value);                                }                                // case 4 does not apply here since attributes can't use                                // default namespace                            }                            continue;                        }                    }                    uri = fSymbolTable.addSymbol(uri);                    // find if for this prefix a URI was already declared                    String declaredURI =  fNSBinder.getURI(prefix);                    if (prefix == XMLSymbols.EMPTY_STRING || declaredURI != uri) {                        // attribute has no prefix (default namespace decl does not apply to attributes)                         // OR                        // attribute prefix is not declared                        // OR                        // conflict: attr URI does not match the prefix in scope                        name  = attr.getNodeName();                        // Find if any prefix for attributes namespace URI is available                        // in the scope                        String declaredPrefix = fNSBinder.getPrefix(uri);                        if (declaredPrefix !=null && declaredPrefix !=XMLSymbols.EMPTY_STRING) {                            // use the prefix that was found                            prefix = declaredPrefix;                            name=prefix+":"+localpart;                        } else {                            if (DEBUG) {                                System.out.println("==> cound not find prefix for the attribute: " +prefix);                            }                            if (prefix != XMLSymbols.EMPTY_STRING && fLocalNSBinder.getURI(prefix) == null) {                                // the current prefix is not null and it has no in scope declaration                                // use this prefix                            } else {                                // find a prefix following the pattern "NS" +index (starting at 1)                                // make sure this prefix is not declared in the current scope.                                int counter = 1;                                prefix = fSymbolTable.addSymbol(PREFIX + counter++);                                while (fLocalNSBinder.getURI(prefix)!=null) {                                    prefix = fSymbolTable.addSymbol(PREFIX +counter++);                                }                                name=prefix+":"+localpart;                            }                            // add declaration for the new prefix                            if (fNamespacePrefixes) {                                printNamespaceAttr(prefix, uri);                            }                            value = fSymbolTable.addSymbol(value);                            fLocalNSBinder.declarePrefix(prefix, value);                            fNSBinder.declarePrefix(prefix, uri);                        }                                                // change prefix for this attribute                    }                    printAttribute (name, (value==null)?XMLSymbols.EMPTY_STRING:value, attr.getSpecified(), attr);                } else { // attribute uri == null                    if (attr.getLocalName() == null) {                        if (fDOMErrorHandler != null) {                            String msg = DOMMessageFormatter.formatMessage(                                DOMMessageFormatter.DOM_DOMAIN,                                 "NullLocalAttrName", new Object[]{attr.getNodeName()});                                                        modifyDOMError(msg, DOMError.SEVERITY_ERROR, null, attr);                            boolean continueProcess = fDOMErrorHandler.handleError(fDOMError);                            if (!continueProcess) {                                // stop the namespace fixup and validation                                throw new RuntimeException(             	                   DOMMessageFormatter.formatMessage(            	                   DOMMessageFormatter.SERIALIZER_DOMAIN,            	                   "SerializationStopped", null));                            }                        }                        printAttribute (name, value, attr.getSpecified(), attr);                    } else { // uri=null and no colon                        // no fix up is needed: default namespace decl does not                         // apply to attributes                        printAttribute (name, value, attr.getSpecified(), attr);                    }                }            } // end loop for attributes        }// end namespace fixup algorithm        // If element has children, then serialize them, otherwise        // serialize en empty tag.                if (elem.hasChildNodes()) {            // Enter an element state, and serialize the children            // one by one. Finally, end the element.            state = enterElementState( null, null, tagName, fPreserveSpace );            state.doCData = _format.isCDataElement( tagName );            state.unescaped = _format.isNonEscapingElement( tagName );            child = elem.getFirstChild();            while (child != null) {                serializeNode( child );                child = child.getNextSibling();            }            if (fNamespaces) {                fNSBinder.popContext();            }            endElementIO( null, null, tagName );        } else {            if (DEBUG) {                System.out.println("==>endElement: " +elem.getNodeName());            }            if (fNamespaces) {                fNSBinder.popContext();            }            _printer.unindent();            _printer.printText( "/>" );            // After element but parent element is no longer empty.            state.afterElement = true;            state.afterComment = false;            state.empty = false;            if (isDocumentState())                _printer.flush();        }    }    /**     * Serializes a namespace attribute with the given prefix and value for URI.     * In case prefix is empty will serialize default namespace declaration.     *      * @param prefix     * @param uri     * @exception IOException     */    private void printNamespaceAttr(String prefix, String uri) throws IOException{

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?