protected void initNamespaces() { this.namespaces = new HashMap<String, Namespace>(); Element root = this.getRoot(); this.namespaces.put(root.getNamespace().getPrefix().toLowerCase(), root.getNamespace()); for (Namespace a : (List<Namespace>) root.getAdditionalNamespaces()) { this.namespaces.put(a.getPrefix().toLowerCase(), a); } }
/** * Collects all namespaces found from the current element and from its all children. The initial * call should pass either an empty {@code List} or a [@code null} value. * * @param element the element from which the namespaces are recursively collected. * @param list the current list of collected namespaces, or {@code null}, if none yet. * @return List of all namespaces which differ either in uri or in prefix. The returned list * contains each unique pair only once. */ public static List<Namespace> collect_namespaces(Element element, List<Namespace> list) { // Breadth-first List<Namespace> pset = new LinkedList<Namespace>(); // First: collect all namespaces present in the current element // The namespace of the XML element itself, or null if none. Namespace pns = element.getNamespace(); if (pns != null) { pset.add(pns); } // The additional namespace declarations present in this XML element. for (Object obj : element.getAdditionalNamespaces()) { pset.add((Namespace) obj); } // for // Second: insert all those namespaces into the master list // which aren't already there. if (list == null) { list = new LinkedList<Namespace>(); } for (Namespace ns : pset) { // Ignore default namespaces. if (ns.getPrefix().equals("")) { continue; } // if: default ns // If the exactly same ns is already in the return list, // do nothing. if (contains_same_ns(list, ns)) { continue; } // if: already there // Otherwise, good to add list.add(ns); } // for: each ns defined in the current elemenet // Then pass the list to all children to populate for (Object obj : element.getContent()) { if ((obj instanceof Element) == false) { continue; } // if list = collect_namespaces((Element) obj, list); } // for: each child return list; } // collect_namespaces()
/** * Purging unused declarations is less optimal, performance-wise, than never adding them in the * first place. So, we should still ask the ROME guys to fix their code (not adding dozens of * unnecessary module declarations). Having said that: purging them here, before XML generation, * is more efficient than parsing and re-molding the XML after ROME generates it. * * <p>Note that the calling app could still add declarations/modules to the Feed tree after this. * Which is fine. But those modules are then responsible for crawling to the root of the tree, at * generate() time, to make sure their namespace declarations are present. */ protected static void purgeUnusedNamespaceDeclarations(Element root) { java.util.Set usedPrefixes = new java.util.HashSet(); collectUsedPrefixes(root, usedPrefixes); List list = root.getAdditionalNamespaces(); List additionalNamespaces = new java.util.ArrayList(); additionalNamespaces.addAll( list); // the duplication will prevent a ConcurrentModificationException below for (int i = 0; i < additionalNamespaces.size(); i++) { Namespace ns = (Namespace) additionalNamespaces.get(i); String prefix = ns.getPrefix(); if (prefix != null && prefix.length() > 0 && !usedPrefixes.contains(prefix)) { root.removeNamespaceDeclaration(ns); } } }
static void rawGetPrefixes(Element element, String namespaceURI, List<String> prefixes) { if (element.getNamespaceURI().equals(namespaceURI)) { prefixes.add(element.getNamespacePrefix()); } List<?> namespaces = element.getAdditionalNamespaces(); for (Iterator<?> itr = namespaces.iterator(); itr.hasNext(); ) { Namespace ns = (Namespace) itr.next(); if (ns.getURI().equals(namespaceURI)) { prefixes.add(ns.getPrefix()); } } if (element.getParentElement() != null) { rawGetPrefixes(element.getParentElement(), namespaceURI, prefixes); } }
public static String rawGetPrefix(Element element, String namespaceURI) { if (element.getNamespaceURI().equals(namespaceURI)) { return element.getNamespacePrefix(); } List<?> namespaces = element.getAdditionalNamespaces(); for (Iterator<?> itr = namespaces.iterator(); itr.hasNext(); ) { Namespace ns = (Namespace) itr.next(); if (ns.getURI().equals(namespaceURI)) { return ns.getPrefix(); } } if (element.getParentElement() != null) { return rawGetPrefix(element.getParentElement(), namespaceURI); } else { return null; } }
/** * This will invoke the <code>ContentHandler.startPrefixMapping</code> callback when a new * namespace is encountered in the <code>Document</code>. * * @param element <code>Element</code> used in callbacks. * @param namespaces <code>List</code> stack of Namespaces in scope. * @return <code>Attributes</code> declaring the namespaces local to <code>element</code> or * <code>null</code>. */ private Attributes startPrefixMapping(Element element, NamespaceStack namespaces) throws JDOMException { AttributesImpl nsAtts = null; // The namespaces as xmlns attributes Namespace ns = element.getNamespace(); if (ns != Namespace.XML_NAMESPACE) { String prefix = ns.getPrefix(); String uri = namespaces.getURI(prefix); if (!ns.getURI().equals(uri)) { namespaces.push(ns); nsAtts = this.addNsAttribute(nsAtts, ns); try { contentHandler.startPrefixMapping(prefix, ns.getURI()); } catch (SAXException se) { throw new JDOMException("Exception in startPrefixMapping", se); } } } // Fire additional namespace declarations List additionalNamespaces = element.getAdditionalNamespaces(); if (additionalNamespaces != null) { Iterator itr = additionalNamespaces.iterator(); while (itr.hasNext()) { ns = (Namespace) itr.next(); String prefix = ns.getPrefix(); String uri = namespaces.getURI(prefix); if (!ns.getURI().equals(uri)) { namespaces.push(ns); nsAtts = this.addNsAttribute(nsAtts, ns); try { contentHandler.startPrefixMapping(prefix, ns.getURI()); } catch (SAXException se) { throw new JDOMException("Exception in startPrefixMapping", se); } } } } return nsAtts; }
/** * Removes the specified namespaces recursively from all children. * * @param element the element from which the specified namespaces should be removed recursively. * @param list the namespaces to remoev */ public static void remove_namespaces(Element element, List<Namespace> list) { // Depth first for (Object obj : element.getContent()) { if ((obj instanceof Element) == false) { continue; } remove_namespaces((Element) obj, list); } // for // Remove all specified namespaces. Done in a manner which is // independent of the referential equivalence. Also, this is independent // of the Namespace objects equivalence, which accounts only for URI. Namespace pns = element.getNamespace(); if (pns != null) { if (contains_same_ns(list, pns)) { element.removeNamespaceDeclaration(pns); } } // if List<Namespace> del = new LinkedList<Namespace>(); for (Object obj : element.getAdditionalNamespaces()) { Namespace ns = (Namespace) obj; if (contains_same_ns(list, ns)) { // Schedule for deletion; cannot delete immedately, // because it would be concurrent modification del.add(ns); } } // for // Execute deletion for (Namespace ns : del) { // from jdom's javadoc: "If the declaration is not present, // this method does nothing." element.removeNamespaceDeclaration(ns); } // for } // remove_namespaces()
/** * @param args * @throws Exception */ @SuppressWarnings({"unchecked", "unused", "rawtypes"}) public static void main(String[] args) throws Exception { SAXBuilder builder = new SAXBuilder(); // Document doc = builder.build(new File("smsi.wsdl")); // Document doc = builder.build(new File("geoipservice.asmx.xml")); Document doc = builder.build(new File("webService.xml")); Element definition = doc.getRootElement(); /*===========获取definition===========*/ Def def = new Def(); def.setName(definition.getAttributeValue("name")); def.setNameSpace(definition.getAttributeValue("targetNamespace")); for (Object nsp : definition.getAdditionalNamespaces()) { Namespace namespace = (Namespace) nsp; if (namespace.getURI().equalsIgnoreCase(def.getNameSpace())) { def.setPrefix(namespace.getPrefix()); } } final String nodePrefix = definition.getNamespacePrefix(); /*===========获取service===========*/ List<Element> services = definition.getContent( new Filter() { private static final long serialVersionUID = -2303656210661749907L; @Override public boolean matches(Object arg0) { if (arg0 instanceof Element) { Element el = (Element) arg0; if (el.getName().equalsIgnoreCase("service")) { return true; } } return false; } }); for (Element el : services) { Service service = new Service(); service.setName(el.getAttributeValue("name")); /*===========获取port===========*/ List<Element> ports = el.getContent( new Filter() { private static final long serialVersionUID = -4769433000956969166L; @Override public boolean matches(Object arg0) { if (arg0 instanceof Element) { Element el = (Element) arg0; if (el.getName().equalsIgnoreCase("port")) { return true; } } return false; } }); for (Element port_ : ports) { Port port = new Port(); port.setName(port_.getAttributeValue("name")); port.setAddress(((Element) port_.getChildren().get(0)).getAttributeValue("location")); service.getPortList().add(port); /*===========获取bind===========*/ final String bindName = port_.getAttributeValue("binding").replace(def.getPrefix() + ":", ""); List<Element> bindings = definition.getContent( new Filter() { private static final long serialVersionUID = -4754235257534212266L; @Override public boolean matches(Object arg0) { if (arg0 instanceof Element) { Element el = (Element) arg0; if (el.getName().equalsIgnoreCase("binding")) { if (el.getAttributeValue("name").equals(bindName)) { return true; } } } return false; } }); Element bind_ = bindings.get(0); Binding binding = new Binding(); binding.setName(bind_.getAttributeValue("name")); // 获取协议类型 String protocolStr = ((Element) bind_.getChildren().get(0)).getNamespacePrefix(); if (protocolStr.equalsIgnoreCase("soap") || protocolStr.equalsIgnoreCase("soap12")) { binding.setProtocol(protocolStr); } if (protocolStr.equalsIgnoreCase("http")) { binding.setProtocol(((Element) bind_.getChildren().get(0)).getAttributeValue("verb")); } port.setBinding(binding); /*===========获取portType ===========*/ final String portTypeName = bind_.getAttributeValue("type").replace(def.getPrefix() + ":", ""); List<Element> portTypes = definition.getContent( new Filter() { private static final long serialVersionUID = -4044611653581176928L; @Override public boolean matches(Object arg0) { if (arg0 instanceof Element) { Element el = (Element) arg0; if (el.getName().equalsIgnoreCase("portType")) { if (el.getAttributeValue("name").equals(portTypeName)) { return true; } } } return false; } }); Element portType_ = portTypes.get(0); PortType portType = new PortType(); portType.setName(portType_.getAttributeValue("name")); binding.setPortType(portType); /*===========获取operation ===========*/ List<Element> operations = portType_.getContent( new Filter() { private static final long serialVersionUID = -8144179824220839482L; @Override public boolean matches(Object arg0) { if (arg0 instanceof Element) { Element el = (Element) arg0; if (el.getName().equalsIgnoreCase("operation")) { return true; } } return false; } }); for (Element operation_ : operations) { Operation operation = new Operation(); operation.setName(operation_.getAttributeValue("name")); final String operatorName = operation_.getAttributeValue("name"); List<Element> operator_temp = bind_.getContent( new Filter() { private static final long serialVersionUID = -7100509421566120733L; @Override public boolean matches(Object arg0) { if (arg0 instanceof Element) { Element el = (Element) arg0; if (el.getName().equalsIgnoreCase("operation")) { if (el.getAttributeValue("name").equals(operatorName)) { return true; } } } return false; } }); Element el_ = (Element) operator_temp.get(0).getChildren().get(0); if (el_.getNamespacePrefix().equalsIgnoreCase("http")) { operation.setUrl(el_.getAttributeValue("location")); } if (el_.getNamespacePrefix().equalsIgnoreCase("soap") || el_.getNamespacePrefix().equalsIgnoreCase("soap12")) { operation.setUrl(el_.getAttributeValue("soapAction")); } portType.getOperationList().add(operation); /*===========获取message===========*/ List opChildList = operation_.getChildren(); for (Object obj : opChildList) { if (obj instanceof Element) { Element el__ = (Element) obj; /*===========input===========*/ if (el__.getName().equals("input")) { final String inputNameStr = el__.getAttributeValue("message").replace(def.getPrefix() + ":", ""); List<Param> inputParamList = getParamList(definition, inputNameStr, def.getPrefix()); operation.getInput().addAll(inputParamList); } /*===========output===========*/ if (el__.getName().equals("output")) { final String outputNameStr = el__.getAttributeValue("message").replace(def.getPrefix() + ":", ""); List<Param> outputParamList = getParamList(definition, outputNameStr, def.getPrefix()); operation.getOutput().addAll(outputParamList); } } } } } def.getServiceList().add(service); } JSONObject jsonObject = new JSONObject(true); System.out.println(jsonObject.toJSONString(def, true)); }
/** * Bubbles all namespaces present in the element and in its children as close to the element as * possible. The process attempts to bubble all namespaces as up as possible. If at some level the * direct children define conflicting namespace prefixes or multiple prefixes for a single * namespace URI, those namespaces are left there. * * <p> * * @param element bubbles namespaces in the children recursively upwards. * @return The namespaces which can be bubbled from the specified element upstream and which * namespaces caused conflicts in the prefixes. */ public static List<Namespace> bubble_namespaces_greedy(Element element) { // Depth first Map<Element, List<Namespace>> map = new LinkedHashMap<Element, List<Namespace>>(); for (Object obj : element.getContent()) { if ((obj instanceof Element) == false) { continue; } // Depth-first recursion Element c = (Element) obj; List<Namespace> rval = null; rval = bubble_namespaces_greedy(c); map.put(c, rval); } // for // Create a set containing all different namespaces in the children List<Namespace> set = new LinkedList<Namespace>(); for (Map.Entry<Element, List<Namespace>> entry : map.entrySet()) { for (Namespace a : entry.getValue()) { // Pick these into local variables for convenience // and to avoid frequently calling the member methods.. String uri = a.getURI(); String prefix = a.getPrefix(); boolean already = false; for (Namespace b : set) { boolean uri_equal = uri.equals(b.getURI()); boolean prefix_equal = prefix.equals(b.getPrefix()); if (uri_equal & prefix_equal) { // already included already = true; break; } } // for: all total if (already == false) { set.add(a); } // if: not already } // for each ns } // for // The list "set" contains now all namespaces present in all // children. Next the conflicting ones need to be singled out. // Return namespaces for this element List<Namespace> pset = new LinkedList<Namespace>(); Namespace pns = element.getNamespace(); if (pns != null) { pset.add(pns); } for (Object obj : element.getAdditionalNamespaces()) { pset.add((Namespace) obj); } // for // The list "pset" contains now all namespaces present // in the parent element itself. List<Namespace> set2 = new LinkedList<Namespace>(); for (Namespace ns1 : set) { String uri = ns1.getURI(); String prefix = ns1.getPrefix(); boolean conflicting = false; for (Namespace ns2 : set) { if (ns1 == ns2) { continue; } boolean uri_eq = uri.equals(ns2.getURI()); boolean p_eq = prefix.equals(ns2.getPrefix()); if (p_eq != uri_eq) { // Conflict. Drop both ns1 and ns2. set2.add(ns1); conflicting = true; // The ns2 will come.. break; } // if } // for if (conflicting) { continue; } // Make sure that ns1 does not conflict with the parent either for (Namespace ns2 : pset) { if (ns1 == ns2) { continue; } boolean uri_eq = uri.equals(ns2.getURI()); boolean p_eq = prefix.equals(ns2.getPrefix()); if (p_eq != uri_eq) { // Conflict. Drop both ns1 only; it cannot be // propagated more upwards. set2.add(ns1); conflicting = true; break; } // if } } // for // the list "set2" is now a list of all conflicting nodes // in the children set.removeAll(set2); // At this point: // set: a list of all namespaces which can be propagated // upwards without conflicts. // set2: a list of all namespaces which are conflicting for (Map.Entry<Element, List<Namespace>> entry : map.entrySet()) { // see which namespaces can be propagated to this.. List<Namespace> list = entry.getValue(); Element child = entry.getKey(); for (Namespace ns : list) { // ------- Find if ns belongs in set boolean contains = false; String uri = ns.getURI(); String p = ns.getPrefix(); for (Namespace x : set) { boolean uri_eq = uri.equals(x.getURI()); boolean p_eq = p.equals(x.getPrefix()); if (p_eq && uri_eq) { contains = true; break; } } // for // if "ns" is contained in "set", // it can be removed from the child if (contains) { // Namespace "ns" can be propagated child.removeNamespaceDeclaration(ns); } // if: contains } // for } // for // Add all not in pset to the parent List<Namespace> rval = new LinkedList<Namespace>(); for (Namespace ns : set) { String uri = ns.getURI(); String p = ns.getPrefix(); boolean contains = false; for (Namespace x : pset) { boolean uri_eq = uri.equals(x.getURI()); boolean p_eq = p.equals(x.getPrefix()); if (p_eq && uri_eq) { contains = true; break; } } // for if (!contains) { element.addNamespaceDeclaration(ns); rval.add(ns); } } // for rval.addAll(pset); return rval; } // bubble_namespaces_greedy()