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 String attributeName;
579 if (nsPrefix == null) {
580 attributeName = XMLConstants.XMLNS_PREFIX;
581 } else {
582 attributeName = XMLConstants.XMLNS_PREFIX + ":" + nsPrefix;
583 }
584
585 String attributeValue;
586 if (nsURI == null) {
587 attributeValue = "";
588 } else {
589 attributeValue = nsURI;
590 }
591
592 domElement.setAttributeNS(XMLConstants.XMLNS_NS, attributeName, attributeValue);
593 }
594
595
596
597
598
599
600
601
602
603
604
605
606
607 public static String lookupNamespaceURI(Element startingElement, String prefix) {
608 return lookupNamespaceURI(startingElement, null, prefix);
609 }
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625 public static String lookupNamespaceURI(Element startingElement, Element stopingElement, String prefix) {
626 String namespaceURI;
627
628
629 if (startingElement.hasAttributes()) {
630 NamedNodeMap map = startingElement.getAttributes();
631 int length = map.getLength();
632 for (int i = 0; i < length; i++) {
633 Node attr = map.item(i);
634 String attrPrefix = attr.getPrefix();
635 String value = attr.getNodeValue();
636 namespaceURI = attr.getNamespaceURI();
637 if (namespaceURI != null && namespaceURI.equals(XMLConstants.XMLNS_NS)) {
638
639 if (prefix == null && attr.getNodeName().equals(XMLConstants.XMLNS_PREFIX)) {
640
641 return value;
642 } else if (attrPrefix != null && attrPrefix.equals(XMLConstants.XMLNS_PREFIX)
643 && attr.getLocalName().equals(prefix)) {
644
645 return value;
646 }
647 }
648 }
649 }
650
651 if (startingElement != stopingElement) {
652 Element ancestor = getElementAncestor(startingElement);
653 if (ancestor != null) {
654 return lookupNamespaceURI(ancestor, stopingElement, prefix);
655 }
656 }
657
658 return null;
659 }
660
661
662
663
664
665
666
667
668
669
670
671
672
673 public static String lookupPrefix(Element startingElement, String namespaceURI) {
674 return lookupPrefix(startingElement, null, namespaceURI);
675 }
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691 public static String lookupPrefix(Element startingElement, Element stopingElement, String namespaceURI) {
692 String namespace;
693
694
695 if (startingElement.hasAttributes()) {
696 NamedNodeMap map = startingElement.getAttributes();
697 int length = map.getLength();
698 for (int i = 0; i < length; i++) {
699 Node attr = map.item(i);
700 String attrPrefix = attr.getPrefix();
701 String value = attr.getNodeValue();
702 namespace = attr.getNamespaceURI();
703 if (namespace != null && namespace.equals(XMLConstants.XMLNS_NS)) {
704
705 if (attr.getNodeName().equals(XMLConstants.XMLNS_PREFIX)
706 || (attrPrefix != null && attrPrefix.equals(XMLConstants.XMLNS_PREFIX))
707 && value.equals(namespaceURI)) {
708
709 String localname = attr.getLocalName();
710 String foundNamespace = startingElement.lookupNamespaceURI(localname);
711 if (foundNamespace != null && foundNamespace.equals(namespaceURI)) {
712 return localname;
713 }
714 }
715
716 }
717 }
718 }
719
720 if (startingElement != stopingElement) {
721 Element ancestor = getElementAncestor(startingElement);
722 if (ancestor != null) {
723 return lookupPrefix(ancestor, stopingElement, namespaceURI);
724 }
725 }
726
727 return null;
728 }
729
730
731
732
733
734
735
736
737
738
739
740 public static List<Element> getChildElementsByTagNameNS(Element root, String namespaceURI, String localName) {
741 ArrayList<Element> children = new ArrayList<Element>();
742 NodeList childNodes = root.getChildNodes();
743
744 int numOfNodes = childNodes.getLength();
745 Node childNode;
746 Element e;
747 for (int i = 0; i < numOfNodes; i++) {
748 childNode = childNodes.item(i);
749 if (childNode.getNodeType() == Node.ELEMENT_NODE) {
750 e = (Element) childNode;
751 if (DatatypeHelper.safeEquals(e.getNamespaceURI(), namespaceURI)
752 && DatatypeHelper.safeEquals(e.getLocalName(), localName)) {
753 children.add(e);
754 }
755 }
756 }
757
758 return children;
759 }
760
761
762
763
764
765
766
767
768
769
770 public static List<Element> getChildElementsByTagName(Element root, String localName) {
771 ArrayList<Element> children = new ArrayList<Element>();
772 NodeList childNodes = root.getChildNodes();
773
774 int numOfNodes = childNodes.getLength();
775 Node childNode;
776 Element e;
777 for (int i = 0; i < numOfNodes; i++) {
778 childNode = childNodes.item(i);
779 if (childNode.getNodeType() == Node.ELEMENT_NODE) {
780 e = (Element) childNode;
781 if (DatatypeHelper.safeEquals(e.getLocalName(), localName)) {
782 children.add(e);
783 }
784 }
785 }
786
787 return children;
788 }
789
790
791
792
793
794
795
796
797 public static Map<QName, List<Element>> getChildElements(Element root) {
798 Map<QName, List<Element>> children = new HashMap<QName, List<Element>>();
799 NodeList childNodes = root.getChildNodes();
800
801 int numOfNodes = childNodes.getLength();
802 Node childNode;
803 Element e;
804 QName qname;
805 List<Element> elements;
806 for (int i = 0; i < numOfNodes; i++) {
807 childNode = childNodes.item(i);
808 if (childNode.getNodeType() == Node.ELEMENT_NODE) {
809 e = (Element) childNode;
810 qname = getNodeQName(e);
811 elements = children.get(qname);
812 if (elements == null) {
813 elements = new ArrayList<Element>();
814 children.put(qname, elements);
815 }
816
817 elements.add(e);
818 }
819 }
820
821 return children;
822 }
823
824
825
826
827
828
829
830
831 public static Element getElementAncestor(Node currentNode) {
832 Node parent = currentNode.getParentNode();
833 if (parent != null) {
834 short type = parent.getNodeType();
835 if (type == Node.ELEMENT_NODE) {
836 return (Element) parent;
837 }
838 return getElementAncestor(parent);
839 }
840 return null;
841 }
842
843
844
845
846
847
848
849
850 public static String nodeToString(Node node) {
851 StringWriter writer = new StringWriter();
852 writeNode(node, writer);
853 return writer.toString();
854 }
855
856
857
858
859
860
861
862
863 public static String prettyPrintXML(Node node) {
864 StringWriter writer = new StringWriter();
865 writeNode(node, writer, getPrettyPrintParams());
866 return writer.toString();
867 }
868
869
870
871
872
873
874 private static Map<String, Object> getPrettyPrintParams() {
875 if (prettyPrintParams == null) {
876 prettyPrintParams = new LazyMap<String, Object>();
877 prettyPrintParams.put("format-pretty-print", Boolean.TRUE);
878 }
879 return prettyPrintParams;
880 }
881
882
883
884
885
886
887
888
889 public static void writeNode(Node node, Writer output) {
890 writeNode(node, output, null);
891 }
892
893
894
895
896
897
898
899
900
901
902 public static void writeNode(Node node, Writer output, Map<String, Object> serializerParams) {
903 DOMImplementationLS domImplLS = getLSDOMImpl(node);
904
905 LSSerializer serializer = getLSSerializer(domImplLS, serializerParams);
906
907 LSOutput serializerOut = domImplLS.createLSOutput();
908 serializerOut.setCharacterStream(output);
909
910 serializer.write(node, serializerOut);
911 }
912
913
914
915
916
917
918
919
920 public static void writeNode(Node node, OutputStream output) {
921 writeNode(node, output, null);
922 }
923
924
925
926
927
928
929
930
931
932
933
934 public static void writeNode(Node node, OutputStream output, Map<String, Object> serializerParams) {
935 DOMImplementationLS domImplLS = getLSDOMImpl(node);
936
937 LSSerializer serializer = getLSSerializer(domImplLS, serializerParams);
938
939 LSOutput serializerOut = domImplLS.createLSOutput();
940 serializerOut.setByteStream(output);
941
942 serializer.write(node, serializerOut);
943 }
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961 public static LSSerializer getLSSerializer(DOMImplementationLS domImplLS, Map<String, Object> serializerParams) {
962 LSSerializer serializer = domImplLS.createLSSerializer();
963
964 serializer.setFilter(new LSSerializerFilter() {
965
966 public short acceptNode(Node arg0) {
967 return FILTER_ACCEPT;
968 }
969
970 public int getWhatToShow() {
971 return SHOW_ALL;
972 }
973 });
974
975
976 if (serializerParams != null) {
977 DOMConfiguration serializerDOMConfig = serializer.getDomConfig();
978 for (String key : serializerParams.keySet()) {
979 serializerDOMConfig.setParameter(key, serializerParams.get(key));
980 }
981 }
982
983 return serializer;
984 }
985
986
987
988
989
990
991
992 public static DOMImplementationLS getLSDOMImpl(Node node) {
993 DOMImplementation domImpl;
994 if (node instanceof Document) {
995 domImpl = ((Document) node).getImplementation();
996 } else {
997 domImpl = node.getOwnerDocument().getImplementation();
998 }
999
1000 DOMImplementationLS domImplLS = (DOMImplementationLS) domImpl.getFeature("LS", "3.0");
1001 return domImplLS;
1002 }
1003
1004
1005
1006
1007
1008
1009
1010
1011 public static String qnameToContentString(QName qname) {
1012 StringBuffer buf = new StringBuffer();
1013
1014 String prefix = DatatypeHelper.safeTrimOrNullString(qname.getPrefix());
1015 if (prefix != null) {
1016 buf.append(prefix);
1017 buf.append(":");
1018 }
1019 buf.append(qname.getLocalPart());
1020 return buf.toString();
1021 }
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033 public static void rootNamespaces(Element domElement) throws XMLParserException {
1034 rootNamespaces(domElement, domElement);
1035 }
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046 private static void rootNamespaces(Element domElement, Element upperNamespaceSearchBound) throws XMLParserException {
1047 String namespaceURI = null;
1048 String namespacePrefix = domElement.getPrefix();
1049
1050
1051 boolean nsDeclaredOnElement = false;
1052 if (namespacePrefix == null) {
1053 nsDeclaredOnElement = domElement.hasAttributeNS(null, XMLConstants.XMLNS_PREFIX);
1054 } else {
1055 nsDeclaredOnElement = domElement.hasAttributeNS(XMLConstants.XMLNS_NS, namespacePrefix);
1056 }
1057
1058 if (!nsDeclaredOnElement) {
1059
1060
1061 namespaceURI = lookupNamespaceURI(domElement, upperNamespaceSearchBound, namespacePrefix);
1062
1063 if (namespaceURI == null) {
1064
1065
1066 namespaceURI = lookupNamespaceURI(upperNamespaceSearchBound, null, namespacePrefix);
1067 if (namespaceURI != null) {
1068
1069
1070 appendNamespaceDeclaration(domElement, namespaceURI, namespacePrefix);
1071 } else {
1072
1073
1074
1075 if (namespacePrefix != null) {
1076 throw new XMLParserException("Unable to resolve namespace prefix " + namespacePrefix
1077 + " found on element " + getNodeQName(domElement));
1078 }
1079 }
1080 }
1081 }
1082
1083
1084 NamedNodeMap attributes = domElement.getAttributes();
1085 Node attributeNode;
1086 for (int i = 0; i < attributes.getLength(); i++) {
1087 namespacePrefix = null;
1088 namespaceURI = null;
1089 attributeNode = attributes.item(i);
1090
1091
1092 if (attributeNode.getNodeType() != Node.ATTRIBUTE_NODE) {
1093 continue;
1094 }
1095
1096 namespacePrefix = attributeNode.getPrefix();
1097 if (!DatatypeHelper.isEmpty(namespacePrefix)) {
1098
1099
1100 if (namespacePrefix.equals(XMLConstants.XMLNS_PREFIX)
1101 || namespacePrefix.equals(XMLConstants.XML_PREFIX)) {
1102 continue;
1103 }
1104
1105
1106 namespaceURI = lookupNamespaceURI(domElement, upperNamespaceSearchBound, namespacePrefix);
1107 if (namespaceURI == null) {
1108 namespaceURI = lookupNamespaceURI(upperNamespaceSearchBound, null, namespacePrefix);
1109 if (namespaceURI == null) {
1110 throw new XMLParserException("Unable to resolve namespace prefix " + namespacePrefix
1111 + " found on attribute " + getNodeQName(attributeNode) + " found on element "
1112 + getNodeQName(domElement));
1113 }
1114
1115 appendNamespaceDeclaration(domElement, namespaceURI, namespacePrefix);
1116 }
1117 }
1118 }
1119
1120
1121
1122 NodeList childNodes = domElement.getChildNodes();
1123 Node childNode;
1124 for (int i = 0; i < childNodes.getLength(); i++) {
1125 childNode = childNodes.item(i);
1126 if (childNode.getNodeType() == Node.ELEMENT_NODE) {
1127 rootNamespaces((Element) childNode, upperNamespaceSearchBound);
1128 }
1129 }
1130 }
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140 public static boolean isElementNamed(Element e, String ns, String localName) {
1141 return e != null && DatatypeHelper.safeEquals(ns, e.getNamespaceURI())
1142 && DatatypeHelper.safeEquals(localName, e.getLocalName());
1143 }
1144
1145
1146
1147
1148
1149
1150
1151 public static Element getFirstChildElement(Node n) {
1152 Node child = n.getFirstChild();
1153 while (child != null && child.getNodeType() != Node.ELEMENT_NODE) {
1154 child = child.getNextSibling();
1155 }
1156
1157 if (child != null) {
1158 return (Element) child;
1159 } else {
1160 return null;
1161 }
1162 }
1163
1164
1165
1166
1167
1168
1169
1170 public static Element getNextSiblingElement(Node n) {
1171 Node sib = n.getNextSibling();
1172 while (sib != null && sib.getNodeType() != Node.ELEMENT_NODE) {
1173 sib = sib.getNextSibling();
1174 }
1175
1176 if (sib != null) {
1177 return (Element) sib;
1178 } else {
1179 return null;
1180 }
1181 }
1182
1183
1184
1185
1186
1187
1188
1189
1190 public static long durationToLong(String duration) {
1191 Duration xmlDuration = getDataTypeFactory().newDuration(duration);
1192 return xmlDuration.getTimeInMillis(new GregorianCalendar());
1193 }
1194
1195
1196
1197
1198
1199
1200
1201
1202 public static String longToDuration(long duration) {
1203 Duration xmlDuration = getDataTypeFactory().newDuration(duration);
1204 return xmlDuration.toString();
1205 }
1206
1207 }