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.StringWriter;
20 import java.io.Writer;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.GregorianCalendar;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Locale;
27 import java.util.Map;
28 import java.util.StringTokenizer;
29 import java.util.Map.Entry;
30
31 import javax.xml.datatype.DatatypeConfigurationException;
32 import javax.xml.datatype.DatatypeFactory;
33 import javax.xml.datatype.Duration;
34 import javax.xml.namespace.QName;
35 import javax.xml.transform.OutputKeys;
36 import javax.xml.transform.Transformer;
37 import javax.xml.transform.TransformerException;
38 import javax.xml.transform.TransformerFactory;
39 import javax.xml.transform.dom.DOMSource;
40 import javax.xml.transform.stream.StreamResult;
41
42 import org.opensaml.xml.Configuration;
43 import org.opensaml.xml.XMLObject;
44 import org.opensaml.xml.XMLRuntimeException;
45 import org.opensaml.xml.parse.XMLParserException;
46 import org.w3c.dom.Attr;
47 import org.w3c.dom.DOMImplementation;
48 import org.w3c.dom.Document;
49 import org.w3c.dom.Element;
50 import org.w3c.dom.NamedNodeMap;
51 import org.w3c.dom.Node;
52 import org.w3c.dom.NodeList;
53 import org.w3c.dom.Text;
54 import org.w3c.dom.ls.DOMImplementationLS;
55 import org.w3c.dom.ls.LSOutput;
56 import org.w3c.dom.ls.LSSerializer;
57
58
59
60
61 public final class XMLHelper {
62
63
64
65
66
67 public static final String LIST_DELIMITERS = " \n\r\t";
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 public static String lookupNamespaceURI(Element startingElement, Element stopingElement, String prefix) {
630 String namespaceURI;
631
632
633 if (startingElement.hasAttributes()) {
634 NamedNodeMap map = startingElement.getAttributes();
635 int length = map.getLength();
636 for (int i = 0; i < length; i++) {
637 Node attr = map.item(i);
638 String attrPrefix = attr.getPrefix();
639 String value = attr.getNodeValue();
640 namespaceURI = attr.getNamespaceURI();
641 if (namespaceURI != null && namespaceURI.equals(XMLConstants.XMLNS_NS)) {
642
643 if (prefix == null && attr.getNodeName().equals(XMLConstants.XMLNS_PREFIX)) {
644
645 return value;
646 } else if (attrPrefix != null && attrPrefix.equals(XMLConstants.XMLNS_PREFIX)
647 && attr.getLocalName().equals(prefix)) {
648
649 return value;
650 }
651 }
652 }
653 }
654
655 if(startingElement != stopingElement){
656 Element ancestor = getElementAncestor(startingElement);
657 if (ancestor != null) {
658 return lookupNamespaceURI(ancestor, stopingElement, prefix);
659 }
660 }
661
662 return null;
663 }
664
665
666
667
668
669
670
671
672
673
674
675
676
677 public static String lookupPrefix(Element startingElement, String namespaceURI) {
678 return lookupPrefix(startingElement, null, namespaceURI);
679 }
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694 public static String lookupPrefix(Element startingElement, Element stopingElement, String namespaceURI) {
695 String namespace;
696
697
698 if (startingElement.hasAttributes()) {
699 NamedNodeMap map = startingElement.getAttributes();
700 int length = map.getLength();
701 for (int i = 0; i < length; i++) {
702 Node attr = map.item(i);
703 String attrPrefix = attr.getPrefix();
704 String value = attr.getNodeValue();
705 namespace = attr.getNamespaceURI();
706 if (namespace != null && namespace.equals(XMLConstants.XMLNS_NS)) {
707
708 if (attr.getNodeName().equals(XMLConstants.XMLNS_PREFIX)
709 || (attrPrefix != null && attrPrefix.equals(XMLConstants.XMLNS_PREFIX))
710 && value.equals(namespaceURI)) {
711
712 String localname = attr.getLocalName();
713 String foundNamespace = startingElement.lookupNamespaceURI(localname);
714 if (foundNamespace != null && foundNamespace.equals(namespaceURI)) {
715 return localname;
716 }
717 }
718
719 }
720 }
721 }
722
723 if(startingElement != stopingElement){
724 Element ancestor = getElementAncestor(startingElement);
725 if (ancestor != null) {
726 return lookupPrefix(ancestor, stopingElement, namespaceURI);
727 }
728 }
729
730 return null;
731 }
732
733
734
735
736
737
738
739
740
741
742
743 public static List<Element> getChildElementsByTagNameNS(Element root, String namespaceURI, String localName) {
744 ArrayList<Element> children = new ArrayList<Element>();
745 NodeList childNodes = root.getChildNodes();
746
747 int numOfNodes = childNodes.getLength();
748 Node childNode;
749 Element e;
750 for (int i = 0; i < numOfNodes; i++) {
751 childNode = childNodes.item(i);
752 if (childNode.getNodeType() == Node.ELEMENT_NODE) {
753 e = (Element) childNode;
754 if (e.getNamespaceURI().equals(namespaceURI) && e.getLocalName().equals(localName)) {
755 children.add(e);
756 }
757 }
758 }
759
760 return children;
761 }
762
763
764
765
766
767
768
769
770
771
772 public static List<Element> getChildElementsByTagName(Element root, String localName) {
773 ArrayList<Element> children = new ArrayList<Element>();
774 NodeList childNodes = root.getChildNodes();
775
776 int numOfNodes = childNodes.getLength();
777 Node childNode;
778 Element e;
779 for (int i = 0; i < numOfNodes; i++) {
780 childNode = childNodes.item(i);
781 if (childNode.getNodeType() == Node.ELEMENT_NODE) {
782 e = (Element) childNode;
783 if (e.getLocalName().equals(localName)) {
784 children.add(e);
785 }
786 }
787 }
788
789 return children;
790 }
791
792
793
794
795
796
797
798
799 public static Map<QName, List<Element>> getChildElements(Element root) {
800 Map<QName, List<Element>> children = new HashMap<QName, List<Element>>();
801 NodeList childNodes = root.getChildNodes();
802
803 int numOfNodes = childNodes.getLength();
804 Node childNode;
805 Element e;
806 QName qname;
807 List<Element> elements;
808 for (int i = 0; i < numOfNodes; i++) {
809 childNode = childNodes.item(i);
810 if (childNode.getNodeType() == Node.ELEMENT_NODE) {
811 e = (Element) childNode;
812 qname = getNodeQName(e);
813 elements = children.get(qname);
814 if (elements == null) {
815 elements = new ArrayList<Element>();
816 children.put(qname, elements);
817 }
818
819 elements.add(e);
820 }
821 }
822
823 return children;
824 }
825
826
827
828
829
830
831
832
833 public static Element getElementAncestor(Node currentNode) {
834 Node parent = currentNode.getParentNode();
835 if (parent != null) {
836 short type = parent.getNodeType();
837 if (type == Node.ELEMENT_NODE) {
838 return (Element) parent;
839 }
840 return getElementAncestor(parent);
841 }
842 return null;
843 }
844
845
846
847
848
849
850
851
852 public static String nodeToString(Node node) {
853 StringWriter writer = new StringWriter();
854 writeNode(node, writer);
855 return writer.toString();
856 }
857
858
859
860
861
862
863
864
865 public static String prettyPrintXML(Node node) {
866 TransformerFactory tfactory = TransformerFactory.newInstance();
867 Transformer serializer;
868 try {
869 serializer = tfactory.newTransformer();
870 serializer.setOutputProperty(OutputKeys.INDENT, "yes");
871 serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "3");
872
873 StringWriter output = new StringWriter();
874 serializer.transform(new DOMSource(node), new StreamResult(output));
875 return output.toString();
876 } catch (TransformerException e) {
877
878 e.printStackTrace();
879
880 throw new RuntimeException(e);
881 }
882 }
883
884
885
886
887
888
889
890
891 public static void writeNode(Node node, Writer output) {
892 DOMImplementation domImpl = node.getOwnerDocument().getImplementation();
893 DOMImplementationLS domImplLS = (DOMImplementationLS) domImpl.getFeature("LS", "3.0");
894 LSSerializer serializer = domImplLS.createLSSerializer();
895
896 LSOutput serializerOut = domImplLS.createLSOutput();
897 serializerOut.setCharacterStream(output);
898
899 serializer.write(node, serializerOut);
900 }
901
902
903
904
905
906
907
908
909 public static String qnameToContentString(QName qname) {
910 StringBuffer buf = new StringBuffer();
911
912 if (qname.getPrefix() != null) {
913 buf.append(qname.getPrefix());
914 buf.append(":");
915 }
916 buf.append(qname.getLocalPart());
917 return buf.toString();
918 }
919
920
921
922
923
924
925
926
927
928
929
930 public static void rootNamespaces(Element domElement) throws XMLParserException {
931 rootNamespaces(domElement, domElement);
932 }
933
934
935
936
937
938
939
940
941
942
943 private static void rootNamespaces(Element domElement, Element upperNamespaceSearchBound) throws XMLParserException {
944 String namespaceURI = null;
945 String namespacePrefix = domElement.getPrefix();
946
947
948 boolean nsDeclaredOnElement = false;
949 if (namespacePrefix == null) {
950 nsDeclaredOnElement = domElement.hasAttributeNS(null, XMLConstants.XMLNS_PREFIX);
951 } else {
952 nsDeclaredOnElement = domElement.hasAttributeNS(XMLConstants.XMLNS_NS, namespacePrefix);
953 }
954
955 if (!nsDeclaredOnElement) {
956
957
958 namespaceURI = lookupNamespaceURI(domElement, upperNamespaceSearchBound, namespacePrefix);
959
960 if (namespaceURI == null) {
961
962
963 namespaceURI = lookupNamespaceURI(upperNamespaceSearchBound, null, namespacePrefix);
964 if (namespaceURI != null) {
965
966
967 appendNamespaceDeclaration(domElement, namespaceURI, namespacePrefix);
968 } else {
969
970
971
972 if (namespacePrefix != null) {
973 throw new XMLParserException("Unable to resolve namespace prefix " + namespacePrefix
974 + " found on element " + getNodeQName(domElement));
975 }
976 }
977 }
978 }
979
980
981 NamedNodeMap attributes = domElement.getAttributes();
982 Node attributeNode;
983 for (int i = 0; i < attributes.getLength(); i++) {
984 namespacePrefix = null;
985 namespaceURI = null;
986 attributeNode = attributes.item(i);
987
988
989 if (attributeNode.getNodeType() != Node.ATTRIBUTE_NODE) {
990 continue;
991 }
992
993 namespacePrefix = attributeNode.getPrefix();
994 if (!DatatypeHelper.isEmpty(namespacePrefix)) {
995
996
997 if (namespacePrefix.equals(XMLConstants.XMLNS_PREFIX)
998 || namespacePrefix.equals(XMLConstants.XML_PREFIX)) {
999 continue;
1000 }
1001
1002
1003 namespaceURI = lookupNamespaceURI(domElement, upperNamespaceSearchBound, namespacePrefix);
1004 if (namespaceURI == null) {
1005 namespaceURI = lookupNamespaceURI(upperNamespaceSearchBound, null, namespacePrefix);
1006 if (namespaceURI == null) {
1007 throw new XMLParserException("Unable to resolve namespace prefix " + namespacePrefix
1008 + " found on attribute " + getNodeQName(attributeNode) + " found on element "
1009 + getNodeQName(domElement));
1010 }
1011
1012 appendNamespaceDeclaration(domElement, namespaceURI, namespacePrefix);
1013 }
1014 }
1015 }
1016
1017
1018
1019 NodeList childNodes = domElement.getChildNodes();
1020 Node childNode;
1021 for (int i = 0; i < childNodes.getLength(); i++) {
1022 childNode = childNodes.item(i);
1023 if (childNode.getNodeType() == Node.ELEMENT_NODE) {
1024 rootNamespaces((Element) childNode, upperNamespaceSearchBound);
1025 }
1026 }
1027 }
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037 public static boolean isElementNamed(Element e, String ns, String localName) {
1038 return e != null && DatatypeHelper.safeEquals(ns, e.getNamespaceURI())
1039 && DatatypeHelper.safeEquals(localName, e.getLocalName());
1040 }
1041
1042
1043
1044
1045
1046
1047
1048 public static Element getFirstChildElement(Node n) {
1049 Node child = n.getFirstChild();
1050 while (child != null && child.getNodeType() != Node.ELEMENT_NODE) {
1051 child = child.getNextSibling();
1052 }
1053
1054 if (child != null) {
1055 return (Element) child;
1056 } else {
1057 return null;
1058 }
1059 }
1060
1061
1062
1063
1064
1065
1066
1067 public static Element getNextSiblingElement(Node n) {
1068 Node sib = n.getNextSibling();
1069 while (sib != null && sib.getNodeType() != Node.ELEMENT_NODE) {
1070 sib = sib.getNextSibling();
1071 }
1072
1073 if (sib != null) {
1074 return (Element) sib;
1075 } else {
1076 return null;
1077 }
1078 }
1079
1080
1081
1082
1083
1084
1085
1086
1087 public static long durationToLong(String duration) {
1088 Duration xmlDuration = getDataTypeFactory().newDuration(duration);
1089 return xmlDuration.getTimeInMillis(new GregorianCalendar());
1090 }
1091
1092
1093
1094
1095
1096
1097
1098
1099 public static String longToDuration(long duration) {
1100 Duration xmlDuration = getDataTypeFactory().newDuration(duration);
1101 return xmlDuration.toString();
1102 }
1103
1104 }