protected void end(Element element) throws SAXException { // push off last context namespaces.popContext(); String uri = element.getNamespaceURI(); String local = element.getLocalName(); String qName = element.getLocalName(); if ((element.getPrefix() != null) && !"".equals(element.getPrefix())) { qName = element.getPrefix() + ":" + qName; } serializer.endElement(uri, local, qName); }
public Attribute unmarshal(Object value) { if (value instanceof org.w3c.dom.Element) { org.w3c.dom.Element el = (org.w3c.dom.Element) value; String prefix = el.getPrefix(); String namespace = el.getNamespaceURI(); String local = el.getLocalName(); String child = el.getTextContent(); String typeAsString = el.getAttributeNS(NamespacePrefixMapper.XSI_NS, "type"); String lang = el.getAttributeNS(NamespacePrefixMapper.XML_NS, "lang"); QName type = ((typeAsString == null) || (typeAsString.equals(""))) ? null : stringToQName(typeAsString, el); if (type == null) type = ValueConverter.QNAME_XSD_STRING; if (type.equals(ValueConverter.QNAME_XSD_QNAME)) { QName qn = stringToQName(child, el); // TODO: not robust to prefix not predeclared return pFactory.newAttribute(namespace, local, prefix, qn, type); } else if ((lang == null) || (lang.equals(""))) { return pFactory.newAttribute( namespace, local, prefix, vconv.convertToJava(type, child), type); } else { return pFactory.newAttribute( namespace, local, prefix, pFactory.newInternationalizedString(child, lang), type); } } if (value instanceof JAXBElement) { JAXBElement<?> je = (JAXBElement<?>) value; return pFactory.newAttribute(je.getName(), je.getValue(), vconv); } return null; }
protected void handleParent(Element e, NameSpaceSymbTable ns) { if (!e.hasAttributes() && e.getNamespaceURI() == null) { return; } xmlattrStack.push(-1); NamedNodeMap attrs = e.getAttributes(); int attrsLength = attrs.getLength(); for (int i = 0; i < attrsLength; i++) { Attr attribute = (Attr) attrs.item(i); String NName = attribute.getLocalName(); String NValue = attribute.getNodeValue(); if (Constants.NamespaceSpecNS.equals(attribute.getNamespaceURI())) { if (!XML.equals(NName) || !Constants.XML_LANG_SPACE_SpecNS.equals(NValue)) { ns.addMapping(NName, NValue, attribute); } } else if (!"id".equals(NName) && XML_LANG_URI.equals(attribute.getNamespaceURI())) { xmlattrStack.addXmlnsAttr(attribute); } } if (e.getNamespaceURI() != null) { String NName = e.getPrefix(); String NValue = e.getNamespaceURI(); String Name; if (NName == null || NName.equals("")) { NName = "xmlns"; Name = "xmlns"; } else { Name = "xmlns:" + NName; } Attr n = e.getOwnerDocument().createAttributeNS("http://www.w3.org/2000/xmlns/", Name); n.setValue(NValue); ns.addMapping(NName, NValue, n); } }
@Override protected AbstractBeanDefinition parseInternal(Element elem, ParserContext parserContext) { String elemNsPrefix = elem.getPrefix(), elemNsUri = elem.getNamespaceURI(), elemLocalName = elem.getLocalName(); Class<?> beanClass = this.getBeanClass(elem); AbstractBeanDefinition beanDef = BeanDefinitionBuilder.genericBeanDefinition(beanClass).getRawBeanDefinition(); try { this.parseDefinition( parserContext, parserContext.getRegistry(), elem, elemNsPrefix, elemNsUri, elemLocalName, beanDef); } catch (Exception e) { throw new FatalBeanException( String.format( "Unable to parse bean definition (class=%s) XML element (nsPrefix=%s, nsUri=%s, localName=%s).", beanClass, elemNsPrefix, elemNsUri, elemLocalName), e); } return beanDef; }
@Override public void relink_namespace(ThreadContext context) { Element e = (Element) node; e.getOwnerDocument().renameNode(e, e.lookupNamespaceURI(e.getPrefix()), e.getNodeName()); if (e.hasAttributes()) { NamedNodeMap attrs = e.getAttributes(); for (int i = 0; i < attrs.getLength(); i++) { Attr attr = (Attr) attrs.item(i); String nsUri = ""; String prefix = attr.getPrefix(); String nodeName = attr.getNodeName(); if ("xml".equals(prefix)) { nsUri = "http://www.w3.org/XML/1998/namespace"; } else if ("xmlns".equals(prefix) || nodeName.equals("xmlns")) { nsUri = "http://www.w3.org/2000/xmlns/"; } else { nsUri = attr.lookupNamespaceURI(nodeName); } e.getOwnerDocument().renameNode(attr, nsUri, nodeName); } } if (e.hasChildNodes()) { ((XmlNodeSet) children(context)).relink_namespace(context); } }
/** * Creates 'wsu:Id' attribute for wsu:Timestamp needed for signature. * * @param message * @return * @throws ParserException */ private String createTimestampUuid(SoapMessage message) throws ParserException { NodeList timestampList = message .getHeader() .getOwnerDocument() .getElementsByTagNameNS(WSU_NAMESPACE, WSU_TIMESTAMP_LOCAL_NAME); assert timestampList.getLength() <= 1; if (timestampList.getLength() == 1) { assert timestampList.item(0).getNodeType() == Node.ELEMENT_NODE; Element timestamp = (Element) timestampList.item(0); String timestampId = Util.randomNCNameUUID(); Attr wsuId = timestamp.getOwnerDocument().createAttributeNS(WSU_NAMESPACE, WSU_ID_LOCAL_NAME); wsuId.setPrefix(timestamp.getPrefix()); wsuId.setValue(timestampId); timestamp.setAttributeNodeNS(wsuId); timestamp.setIdAttributeNode(wsuId, true); log.trace("Created wsu:Id for wsu:Timestamp: " + timestampId); return timestampId; } log.trace("Timestamp element not found in the message"); return null; }
/** {@inheritDoc} */ public void doLoad(Element self) throws Exception { if (self.hasAttribute(getPropertyName())) { setPropertyValue(self.getAttribute(getPropertyName())); } // Clear namespace declarations. getNamespaces().clear(); // Load all declared additional namespaces on this element. Map<String, String> additionalNamespaces = extractNamespaces(self); if (!StringUtils.isBlank(self.getPrefix())) { // Do not include the namespace corresponding to current element itself. additionalNamespaces.remove(self.getPrefix()); } getNamespaces().putAll(additionalNamespaces); super.doLoad(self); }
/** * Renvoie la r?f?rence du premier ?l?ment du sch?ma avec le nom et l'espace de noms de l'?l?ment * pass? en param?tre. */ public Element referenceElement(final Element el) { final String nom; if (el.getPrefix() == null) nom = el.getNodeName(); else nom = el.getLocalName(); final String espace = el.getNamespaceURI(); final WXSElement element = chercherPremierElement(nom, espace); if (element != null) return (element.getDOMElement()); return (null); }
public static Element createElement(String namespaceURI, String prefixedName) { Document doc = createDocument(); Element elem = doc.createElementNS(namespaceURI, prefixedName); // some TrAX implementations do not perform namespace fixup, declare // namespace if (namespaceURI != null) { String prefix = elem.getPrefix(); if (prefix != null) addNamespaceDeclaration(elem, namespaceURI, prefix); else addNamespaceDeclaration(elem, namespaceURI); } doc.appendChild(elem); return elem; }
public String generateTagName(Element element) { if (element == null) return null; IDOMElement xe = (IDOMElement) element; String tagName = element.getTagName(); if (tagName == null) return null; if (xe.isJSPTag()) { if (tagName.equals(JSPTag.JSP_EXPRESSION)) return JSPTag.EXPRESSION_TOKEN; if (tagName.equals(JSPTag.JSP_DECLARATION)) return JSPTag.DECLARATION_TOKEN; if (tagName.equals(JSPTag.JSP_DIRECTIVE)) return JSPTag.DIRECTIVE_TOKEN; if (tagName.startsWith(JSPTag.JSP_DIRECTIVE)) { int offset = JSPTag.JSP_DIRECTIVE.length() + 1; // after '.' return (JSPTag.DIRECTIVE_TOKEN + tagName.substring(offset)); } return (xe.isCommentTag()) ? tagName : null; } else if (tagName.startsWith(JSPTag.TAG_OPEN)) { if (!tagName.endsWith(JSPTag.TAG_CLOSE)) { // close JSP return (tagName + JSPTag.TAG_CLOSE); } } else if (xe.isCommentTag()) { String prefix = element.getPrefix(); if (prefix.equals(SSI_PREFIX)) { return (SSI_TOKEN + element.getLocalName()); } } else { if (!xe.isJSPTag() && xe.isGlobalTag() && // global tag CMNodeUtil.getElementDeclaration(xe) != null) { String newName = tagName; switch (getTagNameCase(xe)) { case DocumentTypeAdapter.UPPER_CASE: newName = tagName.toUpperCase(Locale.ENGLISH); break; case DocumentTypeAdapter.LOWER_CASE: newName = tagName.toLowerCase(Locale.ENGLISH); break; } if (newName != tagName) { tagName = newName; setTagName(element, tagName); } } } return tagName; }
public static void copyChildElement(SOAPElement parent, Element source) throws SOAPException { String localName = source.getLocalName(); String prefix = source.getPrefix(); String namespaceURI = source.getNamespaceURI(); SOAPElement target; // no prefix? if (StringUtils.isEmpty(prefix)) { /* * element used a non-prefixed name, distinguish between no namespace and * default namespace */ if (StringUtils.isEmpty(namespaceURI)) { // no namespace target = parent.addChildElement(localName); if (log.isTraceEnabled()) log.trace("added child element: " + localName); } else { // default namespace, look for existing prefix at target prefix = getPrefix(namespaceURI, parent); // no prefix for that namespace? if (prefix == null) { prefix = generatePrefix(source, DEFAULT_NAMESPACE_PREFIX); } // BPEL-195 source maps prefix to another URI? else if (!namespaceURI.equals(source.getAttributeNS(BpelConstants.NS_XMLNS, prefix))) { prefix = generatePrefix(source, prefix); } target = parent.addChildElement(localName, prefix, namespaceURI); if (log.isTraceEnabled()) log.trace("added child element: {" + namespaceURI + '}' + prefix + ':' + localName); } } else { target = parent.addChildElement(localName, prefix, namespaceURI); if (log.isTraceEnabled()) log.trace("added child element: {" + namespaceURI + '}' + prefix + ':' + localName); } // namespaces copyNamespaces(target, source); // attributes copyAttributes(target, source); // child nodes copyChildNodes(target, source); }
@Override public ElementNode convert(Element element) { ElementBuilder elementBuilder = NodeBuilderFactory.newElementBuilder(); elementBuilder // .nodeName(element.getNodeName()) // .namespaceURI(element.getNamespaceURI()) // .localPart(element.getLocalName()) // .prefix(element.getPrefix()) // .qualifiedName(null) // TODO .tagName(element.getTagName()) // .textContent(element.getTextContent()); // NamedNodeMap namedNodeMap = element.getAttributes(); for (int index = 0; index < namedNodeMap.getLength(); index++) { Attr attr = (Attr) namedNodeMap.item(index); AttributeNode attributeNode = convert(attr); elementBuilder.attributeNodes(attributeNode); } NodeList nodeList = element.getChildNodes(); for (int index = 0; index < nodeList.getLength(); index++) { org.w3c.dom.Node node = nodeList.item(index); if (org.w3c.dom.Node.TEXT_NODE == node.getNodeType()) { Text textNode = (Text) node; TextNode childText = convert(textNode); elementBuilder.textNodes(childText); } else if (org.w3c.dom.Node.ELEMENT_NODE == node.getNodeType()) { Element elementNode = (Element) node; ElementNode childElement = convert(elementNode); elementBuilder.elementNodes(childElement); } else { // TODO 未完成 } } ElementNode elementNode = elementBuilder.build(); return elementNode; }
@Test public void testNamespaceURIPrefixLocalName() throws Exception { // builderFactory = DocumentBuilderFactory.newInstance(); builderFactory.setNamespaceAware(true); String xml = "<?xml version=\"1.0\"?>" + "<t:root xmlns=\"http://void.com/\" xmlns:t=\"http://t.com/\">" + "<t:item/>" + "<child />" + "<t:item/>" + "</t:root>"; DocumentBuilder builder = builderFactory.newDocumentBuilder(); Document doc = builder.parse(new ByteArrayInputStream(xml.getBytes())); Element root = doc.getDocumentElement(); Assert.assertEquals("namespace uri", "http://t.com/", root.getNamespaceURI()); Assert.assertEquals("local name", "root", root.getLocalName()); Assert.assertEquals("prefix", "t", root.getPrefix()); Assert.assertEquals("node name", "t:root", root.getNodeName()); }
protected static String nodeToString(Node node, Set<String> parentPrefixes, String namespaceURI) throws Exception { StringBuilder b = new StringBuilder(); if (node == null) { return ""; } if (node instanceof Element) { Element element = (Element) node; b.append("<"); b.append(element.getNodeName()); Map<String, String> thisLevelPrefixes = new HashMap<>(); if (element.getPrefix() != null && !parentPrefixes.contains(element.getPrefix())) { thisLevelPrefixes.put(element.getPrefix(), element.getNamespaceURI()); } if (element.hasAttributes()) { NamedNodeMap map = element.getAttributes(); for (int i = 0; i < map.getLength(); i++) { Node attr = map.item(i); if (attr.getNodeName().startsWith("xmlns")) continue; if (attr.getPrefix() != null && !parentPrefixes.contains(attr.getPrefix())) { thisLevelPrefixes.put(attr.getPrefix(), element.getNamespaceURI()); } b.append(" "); b.append(attr.getNodeName()); b.append("=\""); b.append(attr.getNodeValue()); b.append("\""); } } if (namespaceURI != null && !thisLevelPrefixes.containsValue(namespaceURI) && !namespaceURI.equals(element.getParentNode().getNamespaceURI())) { b.append(" xmlns=\"").append(namespaceURI).append("\""); } for (Map.Entry<String, String> entry : thisLevelPrefixes.entrySet()) { b.append(" xmlns:") .append(entry.getKey()) .append("=\"") .append(entry.getValue()) .append("\""); parentPrefixes.add(entry.getKey()); } NodeList children = element.getChildNodes(); boolean hasOnlyAttributes = true; for (int i = 0; i < children.getLength(); i++) { Node child = children.item(i); if (child.getNodeType() != Node.ATTRIBUTE_NODE) { hasOnlyAttributes = false; break; } } if (!hasOnlyAttributes) { b.append(">"); for (int i = 0; i < children.getLength(); i++) { b.append( nodeToString(children.item(i), parentPrefixes, children.item(i).getNamespaceURI())); } b.append("</"); b.append(element.getNodeName()); b.append(">"); } else { b.append("/>"); } for (String thisLevelPrefix : thisLevelPrefixes.keySet()) { parentPrefixes.remove(thisLevelPrefix); } } else if (node.getNodeValue() != null) { b.append(encodeText(node.getNodeValue(), node instanceof Attr)); } return b.toString(); }
/** * End processing of given node * * @param node Node we just finished processing * @throws org.xml.sax.SAXException */ protected void endNode(Node node) throws org.xml.sax.SAXException { switch (node.getNodeType()) { case Node.DOCUMENT_NODE: break; case Node.ELEMENT_NODE: String ns = m_dh.getNamespaceOfNode(node); if (null == ns) ns = ""; this.m_contentHandler.endElement(ns, m_dh.getLocalNameOfNode(node), node.getNodeName()); if (m_Serializer == null) { // Don't bother with endPrefixMapping calls if the ContentHandler is a // SerializationHandler because SerializationHandler's ignore the // endPrefixMapping() calls anyways. . . . This is an optimization. Element elem_node = (Element) node; NamedNodeMap atts = elem_node.getAttributes(); int nAttrs = atts.getLength(); // do the endPrefixMapping calls in reverse order // of the startPrefixMapping calls for (int i = (nAttrs - 1); 0 <= i; i--) { final Node attr = atts.item(i); final String attrName = attr.getNodeName(); final int colon = attrName.indexOf(':'); final String prefix; if (attrName.equals("xmlns") || attrName.startsWith("xmlns:")) { // Use "" instead of null, as Xerces likes "" for the // name of the default namespace. Fix attributed // to "Steven Murray" <*****@*****.**>. if (colon < 0) prefix = ""; else prefix = attrName.substring(colon + 1); this.m_contentHandler.endPrefixMapping(prefix); } else if (colon > 0) { prefix = attrName.substring(0, colon); this.m_contentHandler.endPrefixMapping(prefix); } } { String uri = elem_node.getNamespaceURI(); if (uri != null) { String prefix = elem_node.getPrefix(); if (prefix == null) prefix = ""; this.m_contentHandler.endPrefixMapping(prefix); } } } break; case Node.CDATA_SECTION_NODE: break; case Node.ENTITY_REFERENCE_NODE: { EntityReference eref = (EntityReference) node; if (m_contentHandler instanceof LexicalHandler) { LexicalHandler lh = ((LexicalHandler) this.m_contentHandler); lh.endEntity(eref.getNodeName()); } } break; default: } }
/** * Called to serialize a DOM element. Equivalent to calling {@link #startElement}, {@link * #endElement} and serializing everything inbetween, but better optimized. */ protected void serializeElement(Element elem) throws IOException { Attr attr; NamedNodeMap attrMap; int i; Node child; ElementState state; String name; String value; String tagName; String prefix, localUri; String uri; if (fNamespaces) { // local binder stores namespace declaration // that has been printed out during namespace fixup of // the current element fLocalNSBinder.reset(); // add new namespace context fNSBinder.pushContext(); } if (DEBUG) { System.out.println( "==>startElement: " + elem.getNodeName() + " ns=" + elem.getNamespaceURI()); } tagName = elem.getTagName(); state = getElementState(); if (isDocumentState()) { // If this is the root element handle it differently. // If the first root element in the document, serialize // the document's DOCTYPE. Space preserving defaults // to that of the output format. if (!_started) { startDocument(tagName); } } else { // For any other element, if first in parent, then // close parent's opening tag and use the parent's // space preserving. if (state.empty) _printer.printText('>'); // Must leave CData section first if (state.inCData) { _printer.printText("]]>"); state.inCData = false; } // Indent this element on a new line if the first // content of the parent element or immediately // following an element. if (_indenting && !state.preserveSpace && (state.empty || state.afterElement || state.afterComment)) _printer.breakLine(); } // Do not change the current element state yet. // This only happens in endElement(). fPreserveSpace = state.preserveSpace; int length = 0; attrMap = null; // retrieve attributes if (elem.hasAttributes()) { attrMap = elem.getAttributes(); length = attrMap.getLength(); } if (!fNamespaces) { // no namespace fixup should be performed // serialize element name _printer.printText('<'); _printer.printText(tagName); _printer.indent(); // For each attribute print it's name and value as one part, // separated with a space so the element can be broken on // multiple lines. for (i = 0; i < length; ++i) { attr = (Attr) attrMap.item(i); name = attr.getName(); value = attr.getValue(); if (value == null) value = ""; printAttribute(name, value, attr.getSpecified(), attr); } } else { // do namespace fixup // REVISIT: some optimization could probably be done to avoid traversing // attributes twice. // // --------------------------------------- // record all valid namespace declarations // before attempting to fix element's namespace // --------------------------------------- for (i = 0; i < length; i++) { attr = (Attr) attrMap.item(i); uri = attr.getNamespaceURI(); // check if attribute is a namespace decl if (uri != null && uri.equals(NamespaceContext.XMLNS_URI)) { value = attr.getNodeValue(); 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(); } }
/** * Start processing given node * * @param node Node to process * @throws org.xml.sax.SAXException */ protected void startNode(Node node) throws org.xml.sax.SAXException { // TODO: <REVIEW> // A Serializer implements ContentHandler, but not NodeConsumer // so drop this reference to NodeConsumer which would otherwise // pull in all sorts of things // if (m_contentHandler instanceof NodeConsumer) // { // ((NodeConsumer) m_contentHandler).setOriginatingNode(node); // } // TODO: </REVIEW> if (node instanceof Locator) { Locator loc = (Locator) node; m_locator.setColumnNumber(loc.getColumnNumber()); m_locator.setLineNumber(loc.getLineNumber()); m_locator.setPublicId(loc.getPublicId()); m_locator.setSystemId(loc.getSystemId()); } else { m_locator.setColumnNumber(0); m_locator.setLineNumber(0); } switch (node.getNodeType()) { case Node.COMMENT_NODE: { String data = ((Comment) node).getData(); if (m_contentHandler instanceof LexicalHandler) { LexicalHandler lh = ((LexicalHandler) this.m_contentHandler); lh.comment(data.toCharArray(), 0, data.length()); } } break; case Node.DOCUMENT_FRAGMENT_NODE: // ??; break; case Node.DOCUMENT_NODE: break; case Node.ELEMENT_NODE: Element elem_node = (Element) node; { // Make sure the namespace node // for the element itself is declared // to the ContentHandler String uri = elem_node.getNamespaceURI(); if (uri != null) { String prefix = elem_node.getPrefix(); if (prefix == null) prefix = ""; this.m_contentHandler.startPrefixMapping(prefix, uri); } } NamedNodeMap atts = elem_node.getAttributes(); int nAttrs = atts.getLength(); // System.out.println("TreeWalker#startNode: "+node.getNodeName()); // Make sure the namespace node of // each attribute is declared to the ContentHandler for (int i = 0; i < nAttrs; i++) { final Node attr = atts.item(i); final String attrName = attr.getNodeName(); final int colon = attrName.indexOf(':'); final String prefix; // System.out.println("TreeWalker#startNode: attr["+i+"] = "+attrName+", // "+attr.getNodeValue()); if (attrName.equals("xmlns") || attrName.startsWith("xmlns:")) { // Use "" instead of null, as Xerces likes "" for the // name of the default namespace. Fix attributed // to "Steven Murray" <*****@*****.**>. if (colon < 0) prefix = ""; else prefix = attrName.substring(colon + 1); this.m_contentHandler.startPrefixMapping(prefix, attr.getNodeValue()); } else if (colon > 0) { prefix = attrName.substring(0, colon); String uri = attr.getNamespaceURI(); if (uri != null) this.m_contentHandler.startPrefixMapping(prefix, uri); } } String ns = m_dh.getNamespaceOfNode(node); if (null == ns) ns = ""; this.m_contentHandler.startElement( ns, m_dh.getLocalNameOfNode(node), node.getNodeName(), new AttList(atts, m_dh)); break; case Node.PROCESSING_INSTRUCTION_NODE: { ProcessingInstruction pi = (ProcessingInstruction) node; String name = pi.getNodeName(); // String data = pi.getData(); if (name.equals("xslt-next-is-raw")) { nextIsRaw = true; } else { this.m_contentHandler.processingInstruction(pi.getNodeName(), pi.getData()); } } break; case Node.CDATA_SECTION_NODE: { boolean isLexH = (m_contentHandler instanceof LexicalHandler); LexicalHandler lh = isLexH ? ((LexicalHandler) this.m_contentHandler) : null; if (isLexH) { lh.startCDATA(); } dispatachChars(node); { if (isLexH) { lh.endCDATA(); } } } break; case Node.TEXT_NODE: { // String data = ((Text) node).getData(); if (nextIsRaw) { nextIsRaw = false; m_contentHandler.processingInstruction( javax.xml.transform.Result.PI_DISABLE_OUTPUT_ESCAPING, ""); dispatachChars(node); m_contentHandler.processingInstruction( javax.xml.transform.Result.PI_ENABLE_OUTPUT_ESCAPING, ""); } else { dispatachChars(node); } } break; case Node.ENTITY_REFERENCE_NODE: { EntityReference eref = (EntityReference) node; if (m_contentHandler instanceof LexicalHandler) { ((LexicalHandler) this.m_contentHandler).startEntity(eref.getNodeName()); } else { // warning("Can not output entity to a pure SAX ContentHandler"); } } break; default: } }