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 + -
显示快捷键?