Lines 45-52
Link Here
|
45 |
import java.io.IOException; |
45 |
import java.io.IOException; |
46 |
import java.io.OutputStream; |
46 |
import java.io.OutputStream; |
47 |
import java.io.StringReader; |
47 |
import java.io.StringReader; |
|
|
48 |
import java.util.ArrayList; |
49 |
import java.util.Arrays; |
48 |
import java.util.HashMap; |
50 |
import java.util.HashMap; |
49 |
import java.util.HashSet; |
51 |
import java.util.HashSet; |
|
|
52 |
import java.util.Iterator; |
53 |
import java.util.List; |
50 |
import java.util.Map; |
54 |
import java.util.Map; |
51 |
import java.util.Set; |
55 |
import java.util.Set; |
52 |
import javax.xml.parsers.DocumentBuilder; |
56 |
import javax.xml.parsers.DocumentBuilder; |
Lines 66-71
Link Here
|
66 |
import javax.xml.validation.Validator; |
70 |
import javax.xml.validation.Validator; |
67 |
import org.w3c.dom.Attr; |
71 |
import org.w3c.dom.Attr; |
68 |
import org.w3c.dom.CDATASection; |
72 |
import org.w3c.dom.CDATASection; |
|
|
73 |
import org.w3c.dom.Comment; |
69 |
import org.w3c.dom.DOMException; |
74 |
import org.w3c.dom.DOMException; |
70 |
import org.w3c.dom.DOMImplementation; |
75 |
import org.w3c.dom.DOMImplementation; |
71 |
import org.w3c.dom.Document; |
76 |
import org.w3c.dom.Document; |
Lines 842-845
Link Here
|
842 |
} |
847 |
} |
843 |
return doc; |
848 |
return doc; |
844 |
} |
849 |
} |
|
|
850 |
|
851 |
/** |
852 |
* Append child element to the correct position according to given |
853 |
* order. |
854 |
* @param parent parent to which the child will be added |
855 |
* @param el element to be added |
856 |
* @param order order of the elements which must be followed |
857 |
*/ |
858 |
public static void appendChildElement(Element parent, Element el, String[] order) { |
859 |
Element insertBefore = null; |
860 |
List l = Arrays.asList(order); |
861 |
int index = l.indexOf(el.getLocalName()); |
862 |
assert index != -1 : el.getLocalName() + " was not found in " + l; // NOI18N |
863 |
Iterator it = findSubElements(parent).iterator(); |
864 |
while (it.hasNext()) { |
865 |
Element e = (Element) it.next(); |
866 |
int index2 = l.indexOf(e.getLocalName()); |
867 |
assert index2 != -1 : e.getLocalName() + " was not found in " + l; // NOI18N |
868 |
if (index2 > index) { |
869 |
insertBefore = e; |
870 |
break; |
871 |
} |
872 |
} |
873 |
parent.insertBefore(el, insertBefore); |
874 |
} |
875 |
|
876 |
/** |
877 |
* Find all direct child elements of an element. |
878 |
* Children which are all-whitespace text nodes or comments are ignored; others cause |
879 |
* an exception to be thrown. |
880 |
* @param parent a parent element in a DOM tree |
881 |
* @return a list of direct child elements (may be empty) |
882 |
* @throws IllegalArgumentException if there are non-element children besides whitespace |
883 |
*/ |
884 |
public static List<Element> findSubElements(Element parent) throws IllegalArgumentException { |
885 |
NodeList l = parent.getChildNodes(); |
886 |
List<Element> elements = new ArrayList<Element>(l.getLength()); |
887 |
for (int i = 0; i < l.getLength(); i++) { |
888 |
Node n = l.item(i); |
889 |
if (n.getNodeType() == Node.ELEMENT_NODE) { |
890 |
elements.add((Element) n); |
891 |
} else if (n.getNodeType() == Node.TEXT_NODE) { |
892 |
String text = ((Text) n).getNodeValue(); |
893 |
if (text.trim().length() > 0) { |
894 |
throw new IllegalArgumentException("non-ws text encountered in " + parent + ": " + text); // NOI18N |
895 |
} |
896 |
} else if (n.getNodeType() == Node.COMMENT_NODE) { |
897 |
// OK, ignore |
898 |
} else { |
899 |
throw new IllegalArgumentException("unexpected non-element child of " + parent + ": " + n); // NOI18N |
900 |
} |
901 |
} |
902 |
return elements; |
903 |
} |
904 |
|
905 |
/** |
906 |
* Search for an XML element in the direct children of a parent. DOM |
907 |
* provides a similar method but it does a recursive search which we do not |
908 |
* want. It also gives a node list and we want only one result. |
909 |
* |
910 |
* @param parent a parent element |
911 |
* @param name the intended local name |
912 |
* @param namespace the intended namespace (or null) |
913 |
* @return the one child element with that name, or null if none |
914 |
* @throws IllegalArgumentException if there is multiple elements of the same name |
915 |
*/ |
916 |
public static Element findElement(Element parent, String name, String namespace) throws IllegalArgumentException { |
917 |
Element result = null; |
918 |
NodeList l = parent.getChildNodes(); |
919 |
for (int i = 0; i < l.getLength(); i++) { |
920 |
if (l.item(i).getNodeType() == Node.ELEMENT_NODE) { |
921 |
Element el = (Element) l.item(i); |
922 |
if ((namespace == null && name.equals(el.getTagName())) |
923 |
|| (namespace != null && name.equals(el.getLocalName()) && namespace.equals(el.getNamespaceURI()))) { |
924 |
if (result == null) { |
925 |
result = el; |
926 |
} else { |
927 |
throw new IllegalArgumentException("more than one element with same name found"); |
928 |
} |
929 |
} |
930 |
} |
931 |
} |
932 |
return result; |
933 |
} |
934 |
|
935 |
/** |
936 |
* Extract nested text from a node. |
937 |
* Currently does not handle coalescing text nodes, CDATA sections, etc. |
938 |
* @param parent a parent element |
939 |
* @return the nested text, or null if none was found |
940 |
*/ |
941 |
public static String findText(Node parent) { |
942 |
NodeList l = parent.getChildNodes(); |
943 |
for (int i = 0; i < l.getLength(); i++) { |
944 |
if (l.item(i).getNodeType() == Node.TEXT_NODE) { |
945 |
Text text = (Text) l.item(i); |
946 |
return text.getNodeValue(); |
947 |
} |
948 |
} |
949 |
return null; |
950 |
} |
951 |
|
952 |
/** |
953 |
* Convert an XML fragment from one namespace to another. |
954 |
*/ |
955 |
public static Element translateXML(Element from, String namespace) { |
956 |
Element to = from.getOwnerDocument().createElementNS(namespace, from.getLocalName()); |
957 |
NodeList nl = from.getChildNodes(); |
958 |
int length = nl.getLength(); |
959 |
for (int i = 0; i < length; i++) { |
960 |
Node node = nl.item(i); |
961 |
Node newNode; |
962 |
if (node.getNodeType() == Node.ELEMENT_NODE) { |
963 |
newNode = translateXML((Element) node, namespace); |
964 |
} else { |
965 |
newNode = node.cloneNode(true); |
966 |
} |
967 |
to.appendChild(newNode); |
968 |
} |
969 |
NamedNodeMap m = from.getAttributes(); |
970 |
for (int i = 0; i < m.getLength(); i++) { |
971 |
Node attr = m.item(i); |
972 |
to.setAttribute(attr.getNodeName(), attr.getNodeValue()); |
973 |
} |
974 |
return to; |
975 |
} |
976 |
|
977 |
/** |
978 |
* Copy elements from one document to another attaching at the specified element |
979 |
* and translating to the namespace. |
980 |
* |
981 |
* @param doc doc to be copied to |
982 |
* @param from copy the children of this element (exclusive) |
983 |
* @param to where to attach the copied elements |
984 |
* @param newNamespace destination namespace |
985 |
*/ |
986 |
public static void copyDocument(Document doc, Element from, Element to, String newNamespace) { |
987 |
NodeList nl = from.getChildNodes(); |
988 |
int length = nl.getLength(); |
989 |
for (int i = 0; i < length; i++) { |
990 |
Node node = nl.item(i); |
991 |
Node newNode = null; |
992 |
switch (node.getNodeType()) { |
993 |
case Node.ELEMENT_NODE: |
994 |
Element oldElement = (Element) node; |
995 |
newNode = doc.createElementNS(newNamespace, oldElement.getTagName()); |
996 |
NamedNodeMap m = oldElement.getAttributes(); |
997 |
Element newElement = (Element) newNode; |
998 |
for (int index = 0; index < m.getLength(); index++) { |
999 |
Node attr = m.item(index); |
1000 |
newElement.setAttribute(attr.getNodeName(), attr.getNodeValue()); |
1001 |
} |
1002 |
copyDocument(doc, oldElement, newElement, newNamespace); |
1003 |
break; |
1004 |
case Node.TEXT_NODE: |
1005 |
Text oldText = (Text) node; |
1006 |
newNode = doc.createTextNode(oldText.getData()); |
1007 |
break; |
1008 |
case Node.COMMENT_NODE: |
1009 |
Comment oldComment = (Comment) node; |
1010 |
newNode = doc.createComment(oldComment.getData()); |
1011 |
break; |
1012 |
} |
1013 |
if (newNode != null) { |
1014 |
to.appendChild(newNode); |
1015 |
} |
1016 |
} |
1017 |
} |
845 |
} |
1018 |
} |