1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.opensaml.xml.util;
18
19 import java.io.OutputStream;
20 import java.io.StringWriter;
21 import java.io.Writer;
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.GregorianCalendar;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Locale;
28 import java.util.Map;
29 import java.util.StringTokenizer;
30 import java.util.Map.Entry;
31
32 import javax.xml.datatype.DatatypeConfigurationException;
33 import javax.xml.datatype.DatatypeFactory;
34 import javax.xml.datatype.Duration;
35 import javax.xml.namespace.QName;
36
37 import org.opensaml.xml.Configuration;
38 import org.opensaml.xml.XMLObject;
39 import org.opensaml.xml.XMLRuntimeException;
40 import org.opensaml.xml.parse.XMLParserException;
41 import org.w3c.dom.Attr;
42 import org.w3c.dom.DOMConfiguration;
43 import org.w3c.dom.DOMImplementation;
44 import org.w3c.dom.Document;
45 import org.w3c.dom.Element;
46 import org.w3c.dom.NamedNodeMap;
47 import org.w3c.dom.Node;
48 import org.w3c.dom.NodeList;
49 import org.w3c.dom.Text;
50 import org.w3c.dom.ls.DOMImplementationLS;
51 import org.w3c.dom.ls.LSOutput;
52 import org.w3c.dom.ls.LSSerializer;
53 import org.w3c.dom.ls.LSSerializerFilter;
54
55
56
57
58 public final class XMLHelper {
59
60
61
62
63
64 public static final String LIST_DELIMITERS = " \n\r\t";
65
66
67 private static Map<String, Object> prettyPrintParams;
68
69
70 private static DatatypeFactory dataTypeFactory;
71
72
73 private XMLHelper() {
74
75 }
76
77
78
79
80
81
82 public static DatatypeFactory getDataTypeFactory() {
83 if (dataTypeFactory == null) {
84 try {
85 dataTypeFactory = DatatypeFactory.newInstance();
86 } catch (DatatypeConfigurationException e) {
87
88 }
89 }
90
91 return dataTypeFactory;
92 }
93
94
95
96
97
98
99
100
101 public static boolean hasXSIType(Element e) {
102 if (e != null) {
103 if (e.getAttributeNodeNS(XMLConstants.XSI_NS, "type") != null) {
104 return true;
105 }
106 }
107
108 return false;
109 }
110
111
112
113
114
115
116
117
118 public static QName getXSIType(Element e) {
119 if (hasXSIType(e)) {
120 Attr attribute = e.getAttributeNodeNS(XMLConstants.XSI_NS, "type");
121 String attributeValue = attribute.getTextContent().trim();
122 StringTokenizer tokenizer = new StringTokenizer(attributeValue, ":");
123 String prefix = null;
124 String localPart;
125 if (tokenizer.countTokens() > 1) {
126 prefix = tokenizer.nextToken();
127 localPart = tokenizer.nextToken();
128 } else {
129 localPart = tokenizer.nextToken();
130 }
131
132 return constructQName(e.lookupNamespaceURI(prefix), localPart, prefix);
133 }
134
135 return null;
136 }
137
138
139
140
141
142
143
144
145 public static Attr getIdAttribute(Element domElement) {
146 if (!domElement.hasAttributes()) {
147 return null;
148 }
149
150 NamedNodeMap attributes = domElement.getAttributes();
151 Attr attribute;
152 for (int i = 0; i < attributes.getLength(); i++) {
153 attribute = (Attr) attributes.item(i);
154 if (attribute.isId()) {
155 return attribute;
156 }
157 }
158
159 return null;
160 }
161
162
163
164
165
166
167
168
169 public static QName getNodeQName(Node domNode) {
170 if (domNode != null) {
171 return constructQName(domNode.getNamespaceURI(), domNode.getLocalName(), domNode.getPrefix());
172 }
173
174 return null;
175 }
176
177
178
179
180
181
182
183
184
185
186 public static Locale getLanguage(Element element) {
187 String lang = DatatypeHelper.safeTrimOrNullString(element.getAttributeNS(XMLConstants.XML_NS, "lang"));
188 if (lang != null) {
189 if (lang.contains("-")) {
190 lang = lang.substring(0, lang.indexOf("-"));
191 }
192 return new Locale(lang.toUpperCase());
193 } else {
194 return Locale.getDefault();
195 }
196 }
197
198
199
200
201
202
203
204
205
206 public static Attr constructAttribute(Document owningDocument, QName attributeName) {
207 return constructAttribute(owningDocument, attributeName.getNamespaceURI(), attributeName.getLocalPart(),
208 attributeName.getPrefix());
209 }
210
211
212
213
214
215
216
217
218
219
220
221 public static Attr constructAttribute(Document document, String namespaceURI, String localName, String prefix) {
222 String trimmedLocalName = DatatypeHelper.safeTrimOrNullString(localName);
223
224 if (trimmedLocalName == null) {
225 throw new IllegalArgumentException("Local name may not be null or empty");
226 }
227
228 String qualifiedName;
229 String trimmedPrefix = DatatypeHelper.safeTrimOrNullString(prefix);
230 if (trimmedPrefix != null) {
231 qualifiedName = trimmedPrefix + ":" + DatatypeHelper.safeTrimOrNullString(trimmedLocalName);
232 } else {
233 qualifiedName = DatatypeHelper.safeTrimOrNullString(trimmedLocalName);
234 }
235
236 if (DatatypeHelper.isEmpty(namespaceURI)) {
237 return document.createAttributeNS(null, qualifiedName);
238 } else {
239 return document.createAttributeNS(namespaceURI, qualifiedName);
240 }
241 }
242
243
244
245
246
247
248
249
250 public static QName getAttributeValueAsQName(Attr attribute) {
251 if (attribute == null || DatatypeHelper.isEmpty(attribute.getValue())) {
252 return null;
253 }
254
255 String attributeValue = attribute.getTextContent();
256 String[] valueComponents = attributeValue.split(":");
257 if (valueComponents.length == 1) {
258 return constructQName(attribute.lookupNamespaceURI(null), valueComponents[0], null);
259 } else {
260 return constructQName(attribute.lookupNamespaceURI(valueComponents[0]), valueComponents[1],
261 valueComponents[0]);
262 }
263 }
264
265
266
267
268
269
270
271
272
273 public static Boolean getAttributeValueAsBoolean(Attr attribute) {
274 if (attribute == null) {
275 return null;
276 }
277
278 String valueStr = attribute.getValue();
279 if (valueStr.equals("0") || valueStr.equals("false")) {
280 return Boolean.FALSE;
281 } else if (valueStr.equals("1") || valueStr.equals("true")) {
282 return Boolean.TRUE;
283 } else {
284 return null;
285 }
286 }
287
288
289
290
291
292
293
294
295 public static List<String> getAttributeValueAsList(Attr attribute) {
296 if (attribute == null) {
297 return Collections.emptyList();
298 }
299 return DatatypeHelper.stringToList(attribute.getValue(), LIST_DELIMITERS);
300 }
301
302
303
304
305
306
307
308
309
310
311
312 public static void marshallAttribute(QName attributeName, String attributeValue, Element domElement,
313 boolean isIDAttribute) {
314 Document document = domElement.getOwnerDocument();
315 Attr attribute = XMLHelper.constructAttribute(document, attributeName);
316 attribute.setValue(attributeValue);
317 domElement.setAttributeNodeNS(attribute);
318 if (isIDAttribute) {
319 domElement.setIdAttributeNode(attribute, true);
320 }
321 }
322
323
324
325
326
327
328
329
330
331
332
333 public static void marshallAttribute(QName attributeName, List<String> attributeValues, Element domElement,
334 boolean isIDAttribute) {
335 marshallAttribute(attributeName, DatatypeHelper.listToStringValue(attributeValues, " "), domElement,
336 isIDAttribute);
337 }
338
339
340
341
342
343
344
345 public static void marshallAttributeMap(AttributeMap attributeMap, Element domElement) {
346 Document document = domElement.getOwnerDocument();
347 Attr attribute = null;
348 for (Entry<QName, String> entry : attributeMap.entrySet()) {
349 attribute = XMLHelper.constructAttribute(document, entry.getKey());
350 attribute.setValue(entry.getValue());
351 domElement.setAttributeNodeNS(attribute);
352 if (Configuration.isIDAttribute(entry.getKey()) || attributeMap.isIDAttribute(entry.getKey())) {
353 domElement.setIdAttributeNode(attribute, true);
354 }
355 }
356 }
357
358
359
360
361
362
363
364 public static void unmarshallToAttributeMap(AttributeMap attributeMap, Attr attribute) {
365 QName attribQName = XMLHelper.constructQName(attribute.getNamespaceURI(), attribute.getLocalName(), attribute
366 .getPrefix());
367 attributeMap.put(attribQName, attribute.getValue());
368 if (attribute.isId() || Configuration.isIDAttribute(attribQName)) {
369 attributeMap.registerID(attribQName);
370 }
371 }
372
373
374
375
376
377
378
379
380 public static QName getElementContentAsQName(Element element) {
381 if (element == null) {
382 return null;
383 }
384
385 String elementContent = null;
386 NodeList nodeList = element.getChildNodes();
387 for (int i = 0; i < nodeList.getLength(); i++) {
388 Node node = nodeList.item(i);
389 if (node.getNodeType() == Node.TEXT_NODE) {
390 elementContent = DatatypeHelper.safeTrimOrNullString(((Text) node).getWholeText());
391 break;
392 }
393 }
394
395 if (elementContent == null) {
396 return null;
397 }
398
399 String[] valueComponents = elementContent.split(":");
400 if (valueComponents.length == 1) {
401 return constructQName(element.lookupNamespaceURI(null), valueComponents[0], null);
402 } else {
403 return constructQName(element.lookupNamespaceURI(valueComponents[0]), valueComponents[1],
404 valueComponents[0]);
405 }
406 }
407
408
409
410
411
412
413
414
415 public static List<String> getElementContentAsList(Element element) {
416 if (element == null) {
417 return Collections.emptyList();
418 }
419 return DatatypeHelper.stringToList(element.getTextContent(), LIST_DELIMITERS);
420 }
421
422
423
424
425
426
427
428
429
430
431 public static QName constructQName(String namespaceURI, String localName, String prefix) {
432 if (DatatypeHelper.isEmpty(prefix)) {
433 return new QName(namespaceURI, localName);
434 } else if (DatatypeHelper.isEmpty(namespaceURI)) {
435 return new QName(localName);
436 }
437
438 return new QName(namespaceURI, localName, prefix);
439 }
440
441
442
443
444
445
446
447
448
449 public static QName constructQName(String qname, XMLObject owningObject) {
450 return constructQName(qname, owningObject.getDOM());
451 }
452
453
454
455
456
457
458
459
460
461 public static QName constructQName(String qname, Element owningElement) {
462 String nsURI;
463 String nsPrefix;
464 String name;
465
466 if (qname.indexOf(":") > -1) {
467 StringTokenizer qnameTokens = new StringTokenizer(qname, ":");
468 nsPrefix = qnameTokens.nextToken();
469 name = qnameTokens.nextToken();
470 } else {
471 nsPrefix = "";
472 name = qname;
473 }
474
475 nsURI = lookupNamespaceURI(owningElement, nsPrefix);
476 return constructQName(nsURI, name, nsPrefix);
477 }
478
479
480
481
482
483
484
485
486
487 public static Element constructElement(Document document, QName elementName) {
488 return constructElement(document, elementName.getNamespaceURI(), elementName.getLocalPart(), elementName
489 .getPrefix());
490 }
491
492
493
494
495
496
497
498
499
500
501
502 public static Element constructElement(Document document, String namespaceURI, String localName, String prefix) {
503 String trimmedLocalName = DatatypeHelper.safeTrimOrNullString(localName);
504
505 if (trimmedLocalName == null) {
506 throw new IllegalArgumentException("Local name may not be null or empty");
507 }
508
509 String qualifiedName;
510 String trimmedPrefix = DatatypeHelper.safeTrimOrNullString(prefix);
511 if (trimmedPrefix != null) {
512 qualifiedName = trimmedPrefix + ":" + DatatypeHelper.safeTrimOrNullString(trimmedLocalName);
513 } else {
514 qualifiedName = DatatypeHelper.safeTrimOrNullString(trimmedLocalName);
515 }
516
517 if (!DatatypeHelper.isEmpty(namespaceURI)) {
518 return document.createElementNS(namespaceURI, qualifiedName);
519 } else {
520 return document.createElementNS(null, qualifiedName);
521 }
522 }
523
524
525
526
527
528
529
530 public static void appendChildElement(Element parentElement, Element childElement) {
531 Document parentDocument = parentElement.getOwnerDocument();
532 adoptElement(childElement, parentDocument);
533
534 parentElement.appendChild(childElement);
535 }
536
537
538
539
540
541
542
543 public static void adoptElement(Element adoptee, Document adopter) {
544 if (!(adoptee.getOwnerDocument().equals(adopter))) {
545 if (adopter.adoptNode(adoptee) == null) {
546
547 throw new XMLRuntimeException("DOM Element node adoption failed");
548 }
549 }
550 }
551
552
553
554
555
556
557
558 public static void appendTextContent(Element domElement, String textContent) {
559 if (textContent == null) {
560 return;
561 }
562 Document parentDocument = domElement.getOwnerDocument();
563 Text textNode = parentDocument.createTextNode(textContent);
564 domElement.appendChild(textNode);
565 }
566
567
568
569
570
571
572
573
574 public static void appendNamespaceDeclaration(Element domElement, String namespaceURI, String prefix) {
575 String nsURI = DatatypeHelper.safeTrimOrNullString(namespaceURI);
576 String nsPrefix = DatatypeHelper.safeTrimOrNullString(prefix);
577
578
579 if (nsURI == null && nsPrefix == null) {
580 return;
581 }
582
583 String attributeName;
584 if (nsPrefix == null) {
585 attributeName = XMLConstants.XMLNS_PREFIX;
586 } else {
587 attributeName = XMLConstants.XMLNS_PREFIX + ":" + nsPrefix;
588 }
589
590 String attributeValue;
591 if (nsURI == null) {
592 attributeValue = "";
593 } else {
594 attributeValue = nsURI;
595 }
596
597 domElement.setAttributeNS(XMLConstants.XMLNS_NS, attributeName, attributeValue);
598 }
599
600
601
602
603
604
605
606
607
608
609
610
611
612 public static String lookupNamespaceURI(Element startingElement, String prefix) {
613 return lookupNamespaceURI(startingElement, null, prefix);
614 }
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630 public static String lookupNamespaceURI(Element startingElement, Element stopingElement, String prefix) {
631 String namespaceURI;
632
633
634 if (startingElement.hasAttributes()) {
635 NamedNodeMap map = startingElement.getAttributes();
636 int length = map.getLength();
637 for (int i = 0; i < length; i++) {
638 Node attr = map.item(i);
639 String attrPrefix = attr.getPrefix();
640 String value = attr.getNodeValue();
641 namespaceURI = attr.getNamespaceURI();
642 if (namespaceURI != null && namespaceURI.equals(XMLConstants.XMLNS_NS)) {
643
644 if (prefix == null && attr.getNodeName().equals(XMLConstants.XMLNS_PREFIX)) {
645
646 return value;
647 } else if (attrPrefix != null && attrPrefix.equals(XMLConstants.XMLNS_PREFIX)
648 && attr.getLocalName().equals(prefix)) {
649
650 return value;
651 }
652 }
653 }
654 }
655
656 if (startingElement != stopingElement) {
657 Element ancestor = getElementAncestor(startingElement);
658 if (ancestor != null) {
659 return lookupNamespaceURI(ancestor, stopingElement, prefix);
660 }
661 }
662
663 return null;
664 }
665
666
667
668
669
670
671
672
673
674
675
676
677
678 public static String lookupPrefix(Element startingElement, String namespaceURI) {
679 return lookupPrefix(startingElement, null, namespaceURI);
680 }
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696 public static String lookupPrefix(Element startingElement, Element stopingElement, String namespaceURI) {
697 String namespace;
698
699
700 if (startingElement.hasAttributes()) {
701 NamedNodeMap map = startingElement.getAttributes();
702 int length = map.getLength();
703 for (int i = 0; i < length; i++) {
704 Node attr = map.item(i);
705 String attrPrefix = attr.getPrefix();
706 String value = attr.getNodeValue();
707 namespace = attr.getNamespaceURI();
708 if (namespace != null && namespace.equals(XMLConstants.XMLNS_NS)) {
709
710 if (attr.getNodeName().equals(XMLConstants.XMLNS_PREFIX)
711 || (attrPrefix != null && attrPrefix.equals(XMLConstants.XMLNS_PREFIX))
712 && value.equals(namespaceURI)) {
713
714 String localname = attr.getLocalName();
715 String foundNamespace = startingElement.lookupNamespaceURI(localname);
716 if (foundNamespace != null && foundNamespace.equals(namespaceURI)) {
717 return localname;
718 }
719 }
720
721 }
722 }
723 }
724
725 if (startingElement != stopingElement) {
726 Element ancestor = getElementAncestor(startingElement);
727 if (ancestor != null) {
728 return lookupPrefix(ancestor, stopingElement, namespaceURI);
729 }
730 }
731
732 return null;
733 }
734
735
736
737
738
739
740
741
742
743
744
745 public static List<Element> getChildElementsByTagNameNS(Element root, String namespaceURI, String localName) {
746 ArrayList<Element> children = new ArrayList<Element>();
747 NodeList childNodes = root.getChildNodes();
748
749 int numOfNodes = childNodes.getLength();
750 Node childNode;
751 Element e;
752 for (int i = 0; i < numOfNodes; i++) {
753 childNode = childNodes.item(i);
754 if (childNode.getNodeType() == Node.ELEMENT_NODE) {
755 e = (Element) childNode;
756 if (DatatypeHelper.safeEquals(e.getNamespaceURI(), namespaceURI)
757 && DatatypeHelper.safeEquals(e.getLocalName(), localName)) {
758 children.add(e);
759 }
760 }
761 }
762
763 return children;
764 }
765
766
767
768
769
770
771
772
773
774
775 public static List<Element> getChildElementsByTagName(Element root, String localName) {
776 ArrayList<Element> children = new ArrayList<Element>();
777 NodeList childNodes = root.getChildNodes();
778
779 int numOfNodes = childNodes.getLength();
780 Node childNode;
781 Element e;
782 for (int i = 0; i < numOfNodes; i++) {
783 childNode = childNodes.item(i);
784 if (childNode.getNodeType() == Node.ELEMENT_NODE) {
785 e = (Element) childNode;
786 if (DatatypeHelper.safeEquals(e.getLocalName(), localName)) {
787 children.add(e);
788 }
789 }
790 }
791
792 return children;
793 }
794
795
796
797
798
799
800
801
802 public static Map<QName, List<Element>> getChildElements(Element root) {
803 Map<QName, List<Element>> children = new HashMap<QName, List<Element>>();
804 NodeList childNodes = root.getChildNodes();
805
806 int numOfNodes = childNodes.getLength();
807 Node childNode;
808 Element e;
809 QName qname;
810 List<Element> elements;
811 for (int i = 0; i < numOfNodes; i++) {
812 childNode = childNodes.item(i);
813 if (childNode.getNodeType() == Node.ELEMENT_NODE) {
814 e = (Element) childNode;
815 qname = getNodeQName(e);
816 elements = children.get(qname);
817 if (elements == null) {
818 elements = new ArrayList<Element>();
819 children.put(qname, elements);
820 }
821
822 elements.add(e);
823 }
824 }
825
826 return children;
827 }
828
829
830
831
832
833
834
835
836 public static Element getElementAncestor(Node currentNode) {
837 Node parent = currentNode.getParentNode();
838 if (parent != null) {
839 short type = parent.getNodeType();
840 if (type == Node.ELEMENT_NODE) {
841 return (Element) parent;
842 }
843 return getElementAncestor(parent);
844 }
845 return null;
846 }
847
848
849
850
851
852
853
854
855 public static String nodeToString(Node node) {
856 StringWriter writer = new StringWriter();
857 writeNode(node, writer);
858 return writer.toString();
859 }
860
861
862
863
864
865
866
867
868 public static String prettyPrintXML(Node node) {
869 StringWriter writer = new StringWriter();
870 writeNode(node, writer, getPrettyPrintParams());
871 return writer.toString();
872 }
873
874
875
876
877
878
879 private static Map<String, Object> getPrettyPrintParams() {
880 if (prettyPrintParams == null) {
881 prettyPrintParams = new LazyMap<String, Object>();
882 prettyPrintParams.put("format-pretty-print", Boolean.TRUE);
883 }
884 return prettyPrintParams;
885 }
886
887
888
889
890
891
892
893
894 public static void writeNode(Node node, Writer output) {
895 writeNode(node, output, null);
896 }
897
898
899
900
901
902
903
904
905
906
907 public static void writeNode(Node node, Writer output, Map<String, Object> serializerParams) {
908 DOMImplementationLS domImplLS = getLSDOMImpl(node);
909
910 LSSerializer serializer = getLSSerializer(domImplLS, serializerParams);
911
912 LSOutput serializerOut = domImplLS.createLSOutput();
913 serializerOut.setCharacterStream(output);
914
915 serializer.write(node, serializerOut);
916 }
917
918
919
920
921
922
923
924
925 public static void writeNode(Node node, OutputStream output) {
926 writeNode(node, output, null);
927 }
928
929
930
931
932
933
934
935
936
937
938
939 public static void writeNode(Node node, OutputStream output, Map<String, Object> serializerParams) {
940 DOMImplementationLS domImplLS = getLSDOMImpl(node);
941
942 LSSerializer serializer = getLSSerializer(domImplLS, serializerParams);
943
944 LSOutput serializerOut = domImplLS.createLSOutput();
945 serializerOut.setByteStream(output);
946
947 serializer.write(node, serializerOut);
948 }
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966 public static LSSerializer getLSSerializer(DOMImplementationLS domImplLS, Map<String, Object> serializerParams) {
967 LSSerializer serializer = domImplLS.createLSSerializer();
968
969 serializer.setFilter(new LSSerializerFilter() {
970
971 public short acceptNode(Node arg0) {
972 return FILTER_ACCEPT;
973 }
974
975 public int getWhatToShow() {
976 return SHOW_ALL;
977 }
978 });
979
980
981 if (serializerParams != null) {
982 DOMConfiguration serializerDOMConfig = serializer.getDomConfig();
983 for (String key : serializerParams.keySet()) {
984 serializerDOMConfig.setParameter(key, serializerParams.get(key));
985 }
986 }
987
988 return serializer;
989 }
990
991
992
993
994
995
996
997 public static DOMImplementationLS getLSDOMImpl(Node node) {
998 DOMImplementation domImpl;
999 if (node instanceof Document) {
1000 domImpl = ((Document) node).getImplementation();
1001 } else {
1002 domImpl = node.getOwnerDocument().getImplementation();
1003 }
1004
1005 DOMImplementationLS domImplLS = (DOMImplementationLS) domImpl.getFeature("LS", "3.0");
1006 return domImplLS;
1007 }
1008
1009
1010
1011
1012
1013
1014
1015
1016 public static String qnameToContentString(QName qname) {
1017 StringBuffer buf = new StringBuffer();
1018
1019 if (qname.getPrefix() != null) {
1020 buf.append(qname.getPrefix());
1021 buf.append(":");
1022 }
1023 buf.append(qname.getLocalPart());
1024 return buf.toString();
1025 }
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037 public static void rootNamespaces(Element domElement) throws XMLParserException {
1038 rootNamespaces(domElement, domElement);
1039 }
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050 private static void rootNamespaces(Element domElement, Element upperNamespaceSearchBound) throws XMLParserException {
1051 String namespaceURI = null;
1052 String namespacePrefix = domElement.getPrefix();
1053
1054
1055 boolean nsDeclaredOnElement = false;
1056 if (namespacePrefix == null) {
1057 nsDeclaredOnElement = domElement.hasAttributeNS(null, XMLConstants.XMLNS_PREFIX);
1058 } else {
1059 nsDeclaredOnElement = domElement.hasAttributeNS(XMLConstants.XMLNS_NS, namespacePrefix);
1060 }
1061
1062 if (!nsDeclaredOnElement) {
1063
1064
1065 namespaceURI = lookupNamespaceURI(domElement, upperNamespaceSearchBound, namespacePrefix);
1066
1067 if (namespaceURI == null) {
1068
1069
1070 namespaceURI = lookupNamespaceURI(upperNamespaceSearchBound, null, namespacePrefix);
1071 if (namespaceURI != null) {
1072
1073
1074 appendNamespaceDeclaration(domElement, namespaceURI, namespacePrefix);
1075 } else {
1076
1077
1078
1079 if (namespacePrefix != null) {
1080 throw new XMLParserException("Unable to resolve namespace prefix " + namespacePrefix
1081 + " found on element " + getNodeQName(domElement));
1082 }
1083 }
1084 }
1085 }
1086
1087
1088 NamedNodeMap attributes = domElement.getAttributes();
1089 Node attributeNode;
1090 for (int i = 0; i < attributes.getLength(); i++) {
1091 namespacePrefix = null;
1092 namespaceURI = null;
1093 attributeNode = attributes.item(i);
1094
1095
1096 if (attributeNode.getNodeType() != Node.ATTRIBUTE_NODE) {
1097 continue;
1098 }
1099
1100 namespacePrefix = attributeNode.getPrefix();
1101 if (!DatatypeHelper.isEmpty(namespacePrefix)) {
1102
1103
1104 if (namespacePrefix.equals(XMLConstants.XMLNS_PREFIX)
1105 || namespacePrefix.equals(XMLConstants.XML_PREFIX)) {
1106 continue;
1107 }
1108
1109
1110 namespaceURI = lookupNamespaceURI(domElement, upperNamespaceSearchBound, namespacePrefix);
1111 if (namespaceURI == null) {
1112 namespaceURI = lookupNamespaceURI(upperNamespaceSearchBound, null, namespacePrefix);
1113 if (namespaceURI == null) {
1114 throw new XMLParserException("Unable to resolve namespace prefix " + namespacePrefix
1115 + " found on attribute " + getNodeQName(attributeNode) + " found on element "
1116 + getNodeQName(domElement));
1117 }
1118
1119 appendNamespaceDeclaration(domElement, namespaceURI, namespacePrefix);
1120 }
1121 }
1122 }
1123
1124
1125
1126 NodeList childNodes = domElement.getChildNodes();
1127 Node childNode;
1128 for (int i = 0; i < childNodes.getLength(); i++) {
1129 childNode = childNodes.item(i);
1130 if (childNode.getNodeType() == Node.ELEMENT_NODE) {
1131 rootNamespaces((Element) childNode, upperNamespaceSearchBound);
1132 }
1133 }
1134 }
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144 public static boolean isElementNamed(Element e, String ns, String localName) {
1145 return e != null && DatatypeHelper.safeEquals(ns, e.getNamespaceURI())
1146 && DatatypeHelper.safeEquals(localName, e.getLocalName());
1147 }
1148
1149
1150
1151
1152
1153
1154
1155 public static Element getFirstChildElement(Node n) {
1156 Node child = n.getFirstChild();
1157 while (child != null && child.getNodeType() != Node.ELEMENT_NODE) {
1158 child = child.getNextSibling();
1159 }
1160
1161 if (child != null) {
1162 return (Element) child;
1163 } else {
1164 return null;
1165 }
1166 }
1167
1168
1169
1170
1171
1172
1173
1174 public static Element getNextSiblingElement(Node n) {
1175 Node sib = n.getNextSibling();
1176 while (sib != null && sib.getNodeType() != Node.ELEMENT_NODE) {
1177 sib = sib.getNextSibling();
1178 }
1179
1180 if (sib != null) {
1181 return (Element) sib;
1182 } else {
1183 return null;
1184 }
1185 }
1186
1187
1188
1189
1190
1191
1192
1193
1194 public static long durationToLong(String duration) {
1195 Duration xmlDuration = getDataTypeFactory().newDuration(duration);
1196 return xmlDuration.getTimeInMillis(new GregorianCalendar());
1197 }
1198
1199
1200
1201
1202
1203
1204
1205
1206 public static String longToDuration(long duration) {
1207 Duration xmlDuration = getDataTypeFactory().newDuration(duration);
1208 return xmlDuration.toString();
1209 }
1210
1211 }