001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/framework/xml/XMLTools.java $ 002 /*---------------- FILE HEADER ------------------------------------------ 003 004 This file is part of deegree. 005 Copyright (C) 2001-2006 by: 006 EXSE, Department of Geography, University of Bonn 007 http://www.giub.uni-bonn.de/deegree/ 008 lat/lon GmbH 009 http://www.lat-lon.de 010 011 This library is free software; you can redistribute it and/or 012 modify it under the terms of the GNU Lesser General Public 013 License as published by the Free Software Foundation; either 014 version 2.1 of the License, or (at your option) any later version. 015 016 This library is distributed in the hope that it will be useful, 017 but WITHOUT ANY WARRANTY; without even the implied warranty of 018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 019 Lesser General Public License for more details. 020 021 You should have received a copy of the GNU Lesser General Public 022 License along with this library; if not, write to the Free Software 023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 024 025 Contact: 026 027 Andreas Poth 028 lat/lon GmbH 029 Aennchenstr. 19 030 53115 Bonn 031 Germany 032 E-Mail: poth@lat-lon.de 033 034 Prof. Dr. Klaus Greve 035 Department of Geography 036 University of Bonn 037 Meckenheimer Allee 166 038 53115 Bonn 039 Germany 040 E-Mail: greve@giub.uni-bonn.de 041 042 ---------------------------------------------------------------------------*/ 043 044 package org.deegree.framework.xml; 045 046 import java.io.IOException; 047 import java.io.InputStream; 048 import java.io.InputStreamReader; 049 import java.io.Reader; 050 import java.net.URI; 051 import java.net.URISyntaxException; 052 import java.util.ArrayList; 053 import java.util.Iterator; 054 import java.util.List; 055 import java.util.Map; 056 057 import javax.xml.parsers.DocumentBuilder; 058 import javax.xml.parsers.DocumentBuilderFactory; 059 import javax.xml.parsers.ParserConfigurationException; 060 061 import org.deegree.datatypes.QualifiedName; 062 import org.deegree.framework.log.ILogger; 063 import org.deegree.framework.log.LoggerFactory; 064 import org.deegree.framework.util.StringTools; 065 import org.deegree.ogcbase.CommonNamespaces; 066 import org.jaxen.JaxenException; 067 import org.jaxen.XPath; 068 import org.jaxen.dom.DOMXPath; 069 import org.w3c.dom.Attr; 070 import org.w3c.dom.CDATASection; 071 import org.w3c.dom.Comment; 072 import org.w3c.dom.Document; 073 import org.w3c.dom.Element; 074 import org.w3c.dom.NamedNodeMap; 075 import org.w3c.dom.Node; 076 import org.w3c.dom.NodeList; 077 import org.w3c.dom.Text; 078 import org.xml.sax.InputSource; 079 import org.xml.sax.SAXException; 080 081 /** 082 * XML Tools based on JAXP 1.1 for parsing documents and retrieving node values/node attributes. 083 * Furthermore this utility class provides node retrieval based on XPath expressions. 084 * 085 * @author <a href="mailto:mschneider@lat-lon.de">Markus Schneider </a> 086 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a> 087 * @author last edited by: $Author: aschmitz $ 088 * 089 * @version $Revision: 7895 $, $Date: 2007-08-03 11:34:00 +0200 (Fr, 03 Aug 2007) $ 090 */ 091 public final class XMLTools { 092 093 private static final ILogger LOG = LoggerFactory.getLogger( XMLTools.class ); 094 095 private XMLTools() { 096 // hidden constructor to prevent instantiation 097 } 098 099 // ------------------------------------------------------------------------ 100 // XPath based parsing methods 101 // ------------------------------------------------------------------------ 102 103 /** 104 * @param contextNode 105 * @param xPathQuery 106 * @param nsContext 107 * @return Node 108 * @throws XMLParsingException 109 */ 110 public static Node getNode( Node contextNode, String xPathQuery, NamespaceContext nsContext ) 111 throws XMLParsingException { 112 Node node = null; 113 try { 114 XPath xpath = new DOMXPath( xPathQuery ); 115 xpath.setNamespaceContext( nsContext ); 116 node = (Node) xpath.selectSingleNode( contextNode ); 117 118 if ( xPathQuery.endsWith( "text()" ) ) { 119 List<Node> nl = xpath.selectNodes( contextNode ); 120 int pos = xPathQuery.lastIndexOf( "/" ); 121 if ( pos > 0 ) { 122 xPathQuery = xPathQuery.substring( 0, pos ); 123 } else { 124 xPathQuery = "."; 125 } 126 xpath = new DOMXPath( xPathQuery ); 127 xpath.setNamespaceContext( nsContext ); 128 List<Node> nl_ = xpath.selectNodes( contextNode ); 129 List<String> tmp = new ArrayList<String>( nl_.size() ); 130 for ( int i = 0; i < nl_.size(); i++ ) { 131 tmp.add( getStringValue( nl_.get( i ) ) ); 132 } 133 134 for ( int i = 0; i < nl.size(); i++ ) { 135 try { 136 nl.get( i ).getParentNode().removeChild( nl.get( i ) ); 137 } catch ( Exception e ) { 138 // no exception thrown, why catch them? 139 } 140 } 141 142 Document doc = contextNode.getOwnerDocument(); 143 for ( int i = 0; i < tmp.size(); i++ ) { 144 Text text = doc.createTextNode( tmp.get( i ) ); 145 nl_.get( i ).appendChild( text ); 146 node = text; 147 } 148 } 149 150 } catch ( JaxenException e ) { 151 throw new XMLParsingException( "Error evaluating XPath-expression '" + xPathQuery + "' from context node '" 152 + contextNode.getNodeName() + "': " + e.getMessage() ); 153 } 154 return node; 155 } 156 157 /** 158 * @param contextNode 159 * @param xpath 160 * @param nsContext 161 * @return the element 162 * @throws XMLParsingException 163 * @throws ClassCastException 164 * if the node was not an element 165 */ 166 public static Element getElement( Node contextNode, String xpath, NamespaceContext nsContext ) 167 throws XMLParsingException { 168 Node node = getNode( contextNode, xpath, nsContext ); 169 return (Element) node; 170 } 171 172 /** 173 * @param contextNode 174 * @param xPathQuery 175 * @param nsContext 176 * @param defaultValue 177 * @return the node's String value 178 * @throws XMLParsingException 179 */ 180 public static String getNodeAsString( Node contextNode, String xPathQuery, NamespaceContext nsContext, 181 String defaultValue ) 182 throws XMLParsingException { 183 184 String value = defaultValue; 185 Node node = getNode( contextNode, xPathQuery, nsContext ); 186 187 if ( node != null ) { 188 value = getStringValue( node ); 189 } 190 return value; 191 } 192 193 /** 194 * @param contextNode 195 * @param xPathQuery 196 * @param nsContext 197 * @param defaultValue 198 * @return the node's boolean value 199 * @throws XMLParsingException 200 */ 201 public static boolean getNodeAsBoolean( Node contextNode, String xPathQuery, NamespaceContext nsContext, 202 boolean defaultValue ) 203 throws XMLParsingException { 204 boolean value = defaultValue; 205 Node node = getNode( contextNode, xPathQuery, nsContext ); 206 if ( node != null ) { 207 String stringValue = getStringValue( node ); 208 209 if ( "true".equals( stringValue ) || "yes".equals( stringValue ) || "1".equals( stringValue ) ) { 210 value = true; 211 } else if ( "false".equals( stringValue ) || "no".equals( stringValue ) || "0".equals( stringValue ) ) { 212 value = false; 213 } else { 214 throw new XMLParsingException( "XPath-expression '" + xPathQuery + " ' from context node '" 215 + contextNode.getNodeName() + "' has an invalid value ('" + stringValue 216 + "'). Valid values are: 'true', 'yes', '1' " + "'false', 'no' and '0'." ); 217 } 218 } 219 return value; 220 } 221 222 /** 223 * @param contextNode 224 * @param xPathQuery 225 * @param nsContext 226 * @param defaultValue 227 * @return the node's integer value 228 * @throws XMLParsingException 229 */ 230 public static int getNodeAsInt( Node contextNode, String xPathQuery, NamespaceContext nsContext, int defaultValue ) 231 throws XMLParsingException { 232 int value = defaultValue; 233 Node node = getNode( contextNode, xPathQuery, nsContext ); 234 if ( node != null ) { 235 String stringValue = getStringValue( node ); 236 try { 237 value = Integer.parseInt( stringValue ); 238 } catch ( NumberFormatException e ) { 239 throw new XMLParsingException( "Result '" + stringValue + "' of XPath-expression '" + xPathQuery 240 + "' from context node '" + contextNode.getNodeName() 241 + "' does not denote a valid integer value." ); 242 } 243 } 244 return value; 245 } 246 247 /** 248 * @param contextNode 249 * @param xPathQuery 250 * @param nsContext 251 * @param defaultValue 252 * @return the node's double value 253 * @throws XMLParsingException 254 */ 255 public static double getNodeAsDouble( Node contextNode, String xPathQuery, NamespaceContext nsContext, 256 double defaultValue ) 257 throws XMLParsingException { 258 double value = defaultValue; 259 Node node = getNode( contextNode, xPathQuery, nsContext ); 260 if ( node != null ) { 261 String stringValue = getStringValue( node ); 262 try { 263 value = Double.parseDouble( stringValue ); 264 } catch ( NumberFormatException e ) { 265 throw new XMLParsingException( "Result '" + stringValue + "' of XPath-expression '" + xPathQuery 266 + "' from context node '" + contextNode.getNodeName() 267 + "' does not denote a valid double value." ); 268 } 269 } 270 return value; 271 } 272 273 /** 274 * @param contextNode 275 * @param xPathQuery 276 * @param nsContext 277 * @param defaultValue 278 * @return the node as URI 279 * @throws XMLParsingException 280 */ 281 public static URI getNodeAsURI( Node contextNode, String xPathQuery, NamespaceContext nsContext, URI defaultValue ) 282 throws XMLParsingException { 283 URI value = defaultValue; 284 Node node = getNode( contextNode, xPathQuery, nsContext ); 285 if ( node != null ) { 286 String stringValue = getStringValue( node ); 287 try { 288 value = new URI( stringValue ); 289 } catch ( URISyntaxException e ) { 290 throw new XMLParsingException( "Result '" + stringValue + "' of XPath-expression '" + xPathQuery 291 + "' from context node '" + contextNode.getNodeName() 292 + "' does not denote a valid URI." ); 293 } 294 } 295 return value; 296 } 297 298 /** 299 * @param contextNode 300 * @param xPathQuery 301 * @param nsContext 302 * @param defaultValue 303 * @return the node as qualified name 304 * @throws XMLParsingException 305 */ 306 public static QualifiedName getNodeAsQualifiedName( Node contextNode, String xPathQuery, 307 NamespaceContext nsContext, QualifiedName defaultValue ) 308 throws XMLParsingException { 309 310 QualifiedName value = defaultValue; 311 Node node = getNode( contextNode, xPathQuery, nsContext ); 312 313 if ( node != null ) { 314 value = getQualifiedNameValue( node ); 315 } 316 return value; 317 318 } 319 320 /** 321 * returns a list of nodes matching the passed XPath 322 * 323 * @param contextNode 324 * @param xPathQuery 325 * @param nsContext 326 * @return a list of nodes matching the passed XPath 327 * @throws XMLParsingException 328 */ 329 public static List<Node> getNodes( Node contextNode, String xPathQuery, NamespaceContext nsContext ) 330 throws XMLParsingException { 331 List<Node> nl = null; 332 try { 333 XPath xpath = new DOMXPath( xPathQuery ); 334 xpath.setNamespaceContext( nsContext ); 335 nl = xpath.selectNodes( contextNode ); 336 337 if ( xPathQuery.endsWith( "text()" ) ) { 338 339 int pos = xPathQuery.lastIndexOf( "/" ); 340 if ( pos > 0 ) { 341 xPathQuery = xPathQuery.substring( 0, pos ); 342 } else { 343 xPathQuery = "."; 344 } 345 xpath = new DOMXPath( xPathQuery ); 346 xpath.setNamespaceContext( nsContext ); 347 List<?> nl_ = xpath.selectNodes( contextNode ); 348 List<String> tmp = new ArrayList<String>( nl_.size() ); 349 for ( int i = 0; i < nl_.size(); i++ ) { 350 tmp.add( getStringValue( (Node) nl_.get( i ) ) ); 351 } 352 353 for ( int i = 0; i < nl.size(); i++ ) { 354 try { 355 nl.get( i ).getParentNode().removeChild( nl.get( i ) ); 356 } catch ( Exception e ) { 357 // ignored, but why? Nothing is actually thrown here? 358 } 359 } 360 361 nl.clear(); 362 Document doc = contextNode.getOwnerDocument(); 363 for ( int i = 0; i < tmp.size(); i++ ) { 364 Text text = doc.createTextNode( tmp.get( i ) ); 365 ( (Node) nl_.get( i ) ).appendChild( text ); 366 nl.add( text ); 367 } 368 } 369 } catch ( JaxenException e ) { 370 throw new XMLParsingException( "Error evaluating XPath-expression '" + xPathQuery + "' from context node '" 371 + contextNode.getNodeName() + "': " + e.getMessage(), e ); 372 } 373 return nl; 374 } 375 376 /** 377 * @param contextNode 378 * @param xPathQuery 379 * @param nsContext 380 * @return the list of nodes as strings 381 * @throws XMLParsingException 382 */ 383 public static String[] getNodesAsStrings( Node contextNode, String xPathQuery, NamespaceContext nsContext ) 384 throws XMLParsingException { 385 String[] values = null; 386 List<Node> nl = getNodes( contextNode, xPathQuery, nsContext ); 387 if ( nl != null ) { 388 values = new String[nl.size()]; 389 for ( int i = 0; i < nl.size(); i++ ) { 390 values[i] = getStringValue( nl.get( i ) ); 391 } 392 } else { 393 values = new String[0]; 394 } 395 return values; 396 } 397 398 /** 399 * @param contextNode 400 * @param xPathQuery 401 * @param nsContext 402 * @return the nodes as URIs 403 * @throws XMLParsingException 404 */ 405 public static URI[] getNodesAsURIs( Node contextNode, String xPathQuery, NamespaceContext nsContext ) 406 throws XMLParsingException { 407 String[] values = getNodesAsStrings( contextNode, xPathQuery, nsContext ); 408 URI[] uris = new URI[values.length]; 409 for ( int i = 0; i < uris.length; i++ ) { 410 try { 411 uris[i] = new URI( values[i] ); 412 } catch ( URISyntaxException e ) { 413 throw new XMLParsingException( "Result '" + values[i] + "' of XPath-expression '" + xPathQuery 414 + "' from context node '" + contextNode.getNodeName() 415 + "' does not denote a valid URI." ); 416 } 417 } 418 return uris; 419 } 420 421 /** 422 * @param contextNode 423 * @param xPathQuery 424 * @param nsContext 425 * @return the nodes as qualified names 426 * @throws XMLParsingException 427 */ 428 public static QualifiedName[] getNodesAsQualifiedNames( Node contextNode, String xPathQuery, 429 NamespaceContext nsContext ) 430 throws XMLParsingException { 431 432 QualifiedName[] values = null; 433 List<Node> nl = getNodes( contextNode, xPathQuery, nsContext ); 434 if ( nl != null ) { 435 values = new QualifiedName[nl.size()]; 436 for ( int i = 0; i < nl.size(); i++ ) { 437 values[i] = getQualifiedNameValue( nl.get( i ) ); 438 } 439 } else { 440 values = new QualifiedName[0]; 441 } 442 return values; 443 444 } 445 446 /** 447 * @param contextNode 448 * @param xPathQuery 449 * @param nsContext 450 * @return the node 451 * @throws XMLParsingException 452 */ 453 public static Node getRequiredNode( Node contextNode, String xPathQuery, NamespaceContext nsContext ) 454 throws XMLParsingException { 455 Node node = getNode( contextNode, xPathQuery, nsContext ); 456 if ( node == null ) { 457 throw new XMLParsingException( "XPath-expression '" + xPathQuery + "' from context node '" 458 + contextNode.getNodeName() + "' yields no result!" ); 459 } 460 return node; 461 } 462 463 /** 464 * @param contextNode 465 * @param xpath 466 * @param nsContext 467 * @return the element 468 * @throws XMLParsingException 469 * @throws ClassCastException 470 * if the node was not an element 471 */ 472 public static Element getRequiredElement( Node contextNode, String xpath, NamespaceContext nsContext ) 473 throws XMLParsingException { 474 Node node = getRequiredNode( contextNode, xpath, nsContext ); 475 return (Element) node; 476 } 477 478 /** 479 * @param contextNode 480 * @param xPathQuery 481 * @param nsContext 482 * @return the node as string 483 * @throws XMLParsingException 484 */ 485 public static String getRequiredNodeAsString( Node contextNode, String xPathQuery, NamespaceContext nsContext ) 486 throws XMLParsingException { 487 Node node = getRequiredNode( contextNode, xPathQuery, nsContext ); 488 return getStringValue( node ); 489 } 490 491 /** 492 * @param contextNode 493 * the parent of the requested node 494 * @param xPathQuery 495 * the node to get out of the dom 496 * @param nsContext 497 * context of the node 498 * @param validValues 499 * the values that are valid for the required node 500 * @return one of the String valid String values 501 * @throws XMLParsingException 502 * if no Node was found or the text of the Node was not present in the given valid 503 * strings. 504 */ 505 public static String getRequiredNodeAsString( Node contextNode, String xPathQuery, NamespaceContext nsContext, 506 String[] validValues ) 507 throws XMLParsingException { 508 String value = getRequiredNodeAsString( contextNode, xPathQuery, nsContext ); 509 boolean found = false; 510 for ( int i = 0; i < validValues.length; i++ ) { 511 if ( value.equals( validValues[i] ) ) { 512 found = true; 513 break; 514 } 515 } 516 if ( !found ) { 517 StringBuffer sb = new StringBuffer( "XPath-expression '" + xPathQuery + " ' from context node '" 518 + contextNode.getNodeName() 519 + "' has an invalid value. Valid values are: " ); 520 for ( int i = 0; i < validValues.length; i++ ) { 521 sb.append( "'" ).append( validValues[i] ).append( "'" ); 522 if ( i != validValues.length - 1 ) { 523 sb.append( ", " ); 524 } else { 525 sb.append( "." ); 526 } 527 } 528 throw new XMLParsingException( sb.toString() ); 529 } 530 return value; 531 } 532 533 /** 534 * Returns the parts of the targeted node value which are separated by the specified regex. 535 * 536 * @param contextNode 537 * @param xPathQuery 538 * @param nsContext 539 * @param regex 540 * @return the parts of the targeted node value which are separated by the specified regex. 541 * @throws XMLParsingException 542 */ 543 public static String[] getRequiredNodeAsStrings( Node contextNode, String xPathQuery, NamespaceContext nsContext, 544 String regex ) 545 throws XMLParsingException { 546 Node node = getRequiredNode( contextNode, xPathQuery, nsContext ); 547 return StringTools.toArray( getStringValue( node ), regex, false ); 548 } 549 550 /** 551 * @param contextNode 552 * @param xPathQuery 553 * @param nsContext 554 * @return the node as boolean 555 * @throws XMLParsingException 556 */ 557 public static boolean getRequiredNodeAsBoolean( Node contextNode, String xPathQuery, NamespaceContext nsContext ) 558 throws XMLParsingException { 559 boolean value = false; 560 Node node = getRequiredNode( contextNode, xPathQuery, nsContext ); 561 String stringValue = getStringValue( node ); 562 if ( "true".equals( stringValue ) || "yes".equals( stringValue ) ) { 563 value = true; 564 } else if ( "false".equals( stringValue ) || "no".equals( stringValue ) ) { 565 value = false; 566 } else { 567 throw new XMLParsingException( "XPath-expression '" + xPathQuery + " ' from context node '" 568 + contextNode.getNodeName() + "' has an invalid value ('" + stringValue 569 + "'). Valid values are: 'true', 'yes', 'false' and 'no'." ); 570 } 571 572 return value; 573 } 574 575 /** 576 * @param contextNode 577 * @param xPathQuery 578 * @param nsContext 579 * @return the node as integer 580 * @throws XMLParsingException 581 */ 582 public static int getRequiredNodeAsInt( Node contextNode, String xPathQuery, NamespaceContext nsContext ) 583 throws XMLParsingException { 584 585 int value = 0; 586 String stringValue = getRequiredNodeAsString( contextNode, xPathQuery, nsContext ); 587 try { 588 value = Integer.parseInt( stringValue ); 589 } catch ( NumberFormatException e ) { 590 throw new XMLParsingException( "Result '" + stringValue + "' of XPath-expression '" + xPathQuery 591 + "' from context node '" + contextNode.getNodeName() 592 + "' does not denote a valid integer value." ); 593 } 594 return value; 595 } 596 597 /** 598 * @param contextNode 599 * @param xPathQuery 600 * @param nsContext 601 * @return the node as double 602 * @throws XMLParsingException 603 */ 604 public static double getRequiredNodeAsDouble( Node contextNode, String xPathQuery, NamespaceContext nsContext ) 605 throws XMLParsingException { 606 607 double value = 0; 608 String stringValue = getRequiredNodeAsString( contextNode, xPathQuery, nsContext ); 609 try { 610 value = Double.parseDouble( stringValue ); 611 } catch ( NumberFormatException e ) { 612 throw new XMLParsingException( "Result '" + stringValue + "' of XPath-expression '" + xPathQuery 613 + "' from context node '" + contextNode.getNodeName() 614 + "' does not denote a valid double value." ); 615 } 616 return value; 617 } 618 619 /** 620 * Returns the parts of the targeted node value which are separated by the specified regex. The 621 * string parts are converted to doubles. 622 * 623 * @param contextNode 624 * @param xPathQuery 625 * @param nsContext 626 * @param regex 627 * @return the parts of the targeted node value which are separated by the specified regex. 628 * @throws XMLParsingException 629 */ 630 public static double[] getRequiredNodeAsDoubles( Node contextNode, String xPathQuery, NamespaceContext nsContext, 631 String regex ) 632 throws XMLParsingException { 633 String[] parts = getRequiredNodeAsStrings( contextNode, xPathQuery, nsContext, regex ); 634 double[] doubles = new double[parts.length]; 635 for ( int i = 0; i < parts.length; i++ ) { 636 try { 637 doubles[i] = Double.parseDouble( parts[i] ); 638 } catch ( NumberFormatException e ) { 639 throw new XMLParsingException( "Value '" + parts[i] + "' does not denote a valid double value." ); 640 } 641 } 642 return doubles; 643 } 644 645 /** 646 * @param contextNode 647 * @param xPathQuery 648 * @param nsContext 649 * @return the node as URI 650 * @throws XMLParsingException 651 */ 652 public static URI getRequiredNodeAsURI( Node contextNode, String xPathQuery, NamespaceContext nsContext ) 653 throws XMLParsingException { 654 655 URI uri = null; 656 String stringValue = getRequiredNodeAsString( contextNode, xPathQuery, nsContext ); 657 658 try { 659 uri = new URI( stringValue ); 660 } catch ( URISyntaxException e ) { 661 throw new XMLParsingException( "Result '" + stringValue + "' of XPath-expression '" + xPathQuery 662 + "' from context node '" + contextNode.getNodeName() 663 + "' does not denote a valid URI." ); 664 } 665 return uri; 666 } 667 668 /** 669 * @param contextNode 670 * @param xPathQuery 671 * @param nsContext 672 * @return the node as qualified name 673 * @throws XMLParsingException 674 */ 675 public static QualifiedName getRequiredNodeAsQualifiedName( Node contextNode, String xPathQuery, 676 NamespaceContext nsContext ) 677 throws XMLParsingException { 678 Node node = getRequiredNode( contextNode, xPathQuery, nsContext ); 679 return getQualifiedNameValue( node ); 680 } 681 682 /** 683 * @param contextNode 684 * @param xPathQuery 685 * @param nsContext 686 * @return the nodes 687 * @throws XMLParsingException 688 */ 689 public static List<Node> getRequiredNodes( Node contextNode, String xPathQuery, NamespaceContext nsContext ) 690 throws XMLParsingException { 691 List<Node> nl = getNodes( contextNode, xPathQuery, nsContext ); 692 if ( nl.size() == 0 ) { 693 throw new XMLParsingException( "XPath-expression: '" + xPathQuery + "' from context node '" 694 + contextNode.getNodeName() + "' does not yield a result." ); 695 } 696 697 return nl; 698 } 699 700 /** 701 * @param contextNode 702 * @param xpath 703 * @param nsContext 704 * @return a list of Elements 705 * @throws XMLParsingException 706 * @throws ClassCastException 707 * if the resulting nodes of the xpath are not elements 708 */ 709 public static List<Element> getRequiredElements( Node contextNode, String xpath, NamespaceContext nsContext ) 710 throws XMLParsingException { 711 List<Node> nodes = getRequiredNodes( contextNode, xpath, nsContext ); 712 713 List<Element> list = new ArrayList<Element>( nodes.size() ); 714 for ( Node n : nodes ) { 715 list.add( (Element) n ); 716 } 717 718 return list; 719 } 720 721 /** 722 * @param contextNode 723 * @param xpath 724 * @param nsContext 725 * @return a list of Elements 726 * @throws XMLParsingException 727 * @throws ClassCastException 728 * if the resulting nodes of the xpath are not elements 729 */ 730 public static List<Element> getElements( Node contextNode, String xpath, NamespaceContext nsContext ) 731 throws XMLParsingException { 732 List<Node> nodes = getNodes( contextNode, xpath, nsContext ); 733 734 List<Element> list = new ArrayList<Element>( nodes.size() ); 735 for ( Node n : nodes ) { 736 list.add( (Element) n ); 737 } 738 739 return list; 740 } 741 742 /** 743 * Returns the content of the nodes matching the XPathQuery as a String array. At least one node 744 * must match the query otherwise an exception will be thrown. 745 * 746 * @param contextNode 747 * @param xPathQuery 748 * @param nsContext 749 * @return the content of the nodes matching the XPathQuery as a String array. 750 * @throws XMLParsingException 751 */ 752 public static String[] getRequiredNodesAsStrings( Node contextNode, String xPathQuery, NamespaceContext nsContext ) 753 throws XMLParsingException { 754 755 List<Node> nl = getRequiredNodes( contextNode, xPathQuery, nsContext ); 756 757 String[] values = new String[nl.size()]; 758 for ( int i = 0; i < nl.size(); i++ ) { 759 values[i] = getStringValue( nl.get( i ) ); 760 } 761 762 return values; 763 } 764 765 /** 766 * @param contextNode 767 * @param xPathQuery 768 * @param nsContext 769 * @return the qualified names 770 * @throws XMLParsingException 771 */ 772 public static QualifiedName[] getRequiredNodesAsQualifiedNames( Node contextNode, String xPathQuery, 773 NamespaceContext nsContext ) 774 throws XMLParsingException { 775 776 List<Node> nl = getRequiredNodes( contextNode, xPathQuery, nsContext ); 777 778 QualifiedName[] values = new QualifiedName[nl.size()]; 779 for ( int i = 0; i < nl.size(); i++ ) { 780 values[i] = getQualifiedNameValue( nl.get( i ) ); 781 } 782 783 return values; 784 } 785 786 /** 787 * @param value 788 * @param validValues 789 * @throws XMLParsingException 790 */ 791 public static void checkValue( String value, String[] validValues ) 792 throws XMLParsingException { 793 for ( int i = 0; i < validValues.length; i++ ) { 794 if ( validValues[i].equals( value ) ) { 795 return; 796 } 797 } 798 StringBuffer sb = new StringBuffer( "Value '" ).append( value ).append( "' is invalid. Valid values are: " ); 799 for ( int i = 0; i < validValues.length; i++ ) { 800 sb.append( "'" ).append( validValues[i] ).append( "'" ); 801 if ( i != validValues.length - 1 ) { 802 sb.append( ", " ); 803 } else { 804 sb.append( "." ); 805 } 806 } 807 throw new XMLParsingException( sb.toString() ); 808 } 809 810 // ------------------------------------------------------------------------ 811 // Node creation methods 812 // ------------------------------------------------------------------------ 813 814 /** 815 * Creates a new <code>Element</code> node from the given parameters and appends it to the 816 * also specified <code>Element</code>. 817 * 818 * @param element 819 * <code>Element</code> that the new <code>Element</code> is appended to 820 * @param namespaceURI 821 * use null for default namespace 822 * @param name 823 * qualified name 824 * @return the appended <code>Element</code> node 825 */ 826 public static Element appendElement( Element element, URI namespaceURI, String name ) { 827 return appendElement( element, namespaceURI, name, null ); 828 } 829 830 /** 831 * Appends a namespace binding for the specified element that binds the given prefix to the 832 * given namespace using a special attribute: xmlns:prefix=namespace 833 * 834 * @param element 835 * @param prefix 836 * @param namespace 837 */ 838 public static void appendNSBinding( Element element, String prefix, URI namespace ) { 839 Attr attribute = element.getOwnerDocument().createAttributeNS( CommonNamespaces.XMLNS.toASCIIString(), 840 CommonNamespaces.XMLNS_PREFIX + ":" + prefix ); 841 attribute.setNodeValue( namespace.toASCIIString() ); 842 element.getAttributes().setNamedItemNS( attribute ); 843 } 844 845 /** 846 * Appends the default namespace binding for the specified element. 847 * 848 * @param element 849 * @param prefix 850 * @param namespace 851 */ 852 public static void appendNSDefaultBinding( Element element, URI namespace ) { 853 Attr attribute = element.getOwnerDocument().createAttributeNS( CommonNamespaces.XMLNS.toASCIIString(), 854 CommonNamespaces.XMLNS_PREFIX); 855 attribute.setNodeValue( namespace.toASCIIString() ); 856 element.getAttributes().setNamedItemNS( attribute ); 857 } 858 859 /** 860 * Appends the given namespace bindings to the specified element. 861 * <p> 862 * NOTE: The prebound prefix "xml" is skipped. 863 * 864 * @param element 865 * @param nsContext 866 */ 867 public static void appendNSBindings( Element element, NamespaceContext nsContext ) { 868 Map<String, URI> namespaceMap = nsContext.getNamespaceMap(); 869 Iterator<String> prefixIter = namespaceMap.keySet().iterator(); 870 while ( prefixIter.hasNext() ) { 871 String prefix = prefixIter.next(); 872 if ( !CommonNamespaces.XMLNS_PREFIX.equals( prefix ) ) { 873 URI namespace = namespaceMap.get( prefix ); 874 appendNSBinding( element, prefix, namespace ); 875 } 876 } 877 } 878 879 // ------------------------------------------------------------------------ 880 // String value methods 881 // ------------------------------------------------------------------------ 882 883 /** 884 * Returns the text contained in the specified element. 885 * 886 * @param node 887 * current element 888 * @return the textual contents of the element 889 */ 890 public static String getStringValue( Node node ) { 891 NodeList children = node.getChildNodes(); 892 StringBuffer sb = new StringBuffer( children.getLength() * 500 ); 893 if ( node.getNodeValue() != null ) { 894 sb.append( node.getNodeValue().trim() ); 895 } 896 if ( node.getNodeType() != Node.ATTRIBUTE_NODE ) { 897 for ( int i = 0; i < children.getLength(); i++ ) { 898 if ( children.item( i ).getNodeType() == Node.TEXT_NODE 899 || children.item( i ).getNodeType() == Node.CDATA_SECTION_NODE ) { 900 sb.append( children.item( i ).getNodeValue() ); 901 } 902 } 903 } 904 return sb.toString(); 905 } 906 907 /** 908 * Returns the text contained in the specified child element of the given element. 909 * 910 * @param name 911 * name of the child element 912 * @param namespace 913 * namespace of the child element 914 * @param node 915 * current element 916 * @param defaultValue 917 * default value if element is missing 918 * @return the textual contents of the element or the given default value, if missing 919 */ 920 public static String getStringValue( String name, URI namespace, Node node, String defaultValue ) { 921 922 String value = defaultValue; 923 Element element = getChildElement( name, namespace, node ); 924 925 if ( element != null ) { 926 value = getStringValue( element ); 927 } 928 if ( value == null || value.equals( "" ) ) { 929 value = defaultValue; 930 } 931 932 return value; 933 } 934 935 /** 936 * Returns the text contained in the specified child element of the given element. 937 * 938 * @param name 939 * name of the child element 940 * @param namespace 941 * namespace of the child element 942 * @param node 943 * current element 944 * @return the textual contents of the element or null, if it is missing 945 * @throws XMLParsingException 946 * if the specified child element is missing 947 */ 948 public static String getRequiredStringValue( String name, URI namespace, Node node ) 949 throws XMLParsingException { 950 Element element = getRequiredChildElement( name, namespace, node ); 951 return getStringValue( element ); 952 } 953 954 /** 955 * Returns the value of the specified node attribute. 956 * 957 * @param name 958 * name of attribute 959 * @param namespaceURI 960 * namespace of attribute 961 * @param node 962 * current element 963 * @return the textual contents of the attribute 964 * @throws XMLParsingException 965 * if specified attribute is missing 966 */ 967 public static String getRequiredAttrValue( String name, URI namespaceURI, Node node ) 968 throws XMLParsingException { 969 970 String namespace = namespaceURI == null ? null : namespaceURI.toString(); 971 972 String value = null; 973 NamedNodeMap atts = node.getAttributes(); 974 if ( atts != null ) { 975 Attr attribute = null; 976 if ( namespace == null ) { 977 attribute = (Attr) atts.getNamedItem( name ); 978 } else { 979 attribute = (Attr) atts.getNamedItemNS( namespace, name ); 980 } 981 982 if ( attribute != null ) { 983 value = attribute.getValue(); 984 } 985 } 986 if ( value == null ) { 987 throw new XMLParsingException( "Required attribute " + name + '(' + namespaceURI + ") of element " 988 + node.getNodeName() + " is missing." ); 989 } 990 return value; 991 } 992 993 /** 994 * Parses the value of the submitted <code>Node</code> as a <code>QualifiedName</code>. 995 * <p> 996 * To parse the text contents of an <code>Element</code> node, the actual text node must be 997 * given, not the <code>Element</code> node itself. 998 * </p> 999 * 1000 * @param node 1001 * @return object representation of the element 1002 * @throws XMLParsingException 1003 */ 1004 public static QualifiedName getQualifiedNameValue( Node node ) 1005 throws XMLParsingException { 1006 1007 String name = node.getNodeValue().trim(); 1008 QualifiedName qName = null; 1009 if ( name.indexOf( ':' ) > -1 ) { 1010 String[] tmp = StringTools.toArray( name, ":", false ); 1011 try { 1012 qName = new QualifiedName( tmp[0], tmp[1], XMLTools.getNamespaceForPrefix( tmp[0], node ) ); 1013 } catch ( URISyntaxException e ) { 1014 throw new XMLParsingException( e.getMessage(), e ); 1015 } 1016 } else { 1017 qName = new QualifiedName( name ); 1018 } 1019 return qName; 1020 } 1021 1022 /** 1023 * Returns the namespace URI that is bound to a given prefix at a certain node in the DOM tree. 1024 * 1025 * @param prefix 1026 * @param node 1027 * @return namespace URI that is bound to the given prefix, null otherwise 1028 * @throws URISyntaxException 1029 */ 1030 public static URI getNamespaceForPrefix( String prefix, Node node ) 1031 throws URISyntaxException { 1032 if ( node == null ) { 1033 return null; 1034 } 1035 if ( node.getNodeType() == Node.ELEMENT_NODE ) { 1036 NamedNodeMap nnm = node.getAttributes(); 1037 if ( nnm != null ) { 1038 // LOG.logDebug( "(searching namespace for prefix (" + prefix 1039 // + "), resulted in a namedNodeMap for the currentNode: " + node.getNodeName() ); 1040 for ( int i = 0; i < nnm.getLength(); i++ ) { 1041 Attr a = (Attr) nnm.item( i ); 1042 // LOG.logDebug( "\t(searching namespace for prefix (" + prefix + "), resulted in an attribute: " 1043 // + a.getName() ); 1044 1045 if ( a.getName().startsWith( "xmlns:" ) && a.getName().endsWith( ':' + prefix ) ) { 1046 return new URI( a.getValue() ); 1047 } else if ( prefix == null && a.getName().equals( "xmlns" ) ) { 1048 return new URI( a.getValue() ); 1049 } 1050 } 1051 } 1052 } else if ( node.getNodeType() == Node.ATTRIBUTE_NODE ) { 1053 return getNamespaceForPrefix( prefix, ( (Attr) node ).getOwnerElement() ); 1054 } 1055 return getNamespaceForPrefix( prefix, node.getParentNode() ); 1056 } 1057 1058 // ------------------------------------------------------------------------ 1059 // Old code - deprecated 1060 // ------------------------------------------------------------------------ 1061 1062 /** 1063 * Returns the specified child element of the given element. If there is more than one element 1064 * with that name, the first one is returned. 1065 * 1066 * @deprecated 1067 * @param name 1068 * name of the child element 1069 * @param namespaceURI 1070 * namespaceURI of the child element 1071 * @param node 1072 * current element 1073 * @return the element or null, if it is missing 1074 * @throws XMLParsingException 1075 * if the specified child element is missing 1076 * @throws XMLParsingException 1077 * @todo refactoring required 1078 */ 1079 @Deprecated 1080 public static Element getRequiredChildElement( String name, URI namespaceURI, Node node ) 1081 throws XMLParsingException { 1082 1083 String namespace = namespaceURI == null ? null : namespaceURI.toString(); 1084 1085 NodeList nl = node.getChildNodes(); 1086 Element element = null; 1087 Element childElement = null; 1088 1089 if ( ( nl != null ) && ( nl.getLength() > 0 ) ) { 1090 for ( int i = 0; i < nl.getLength(); i++ ) { 1091 if ( nl.item( i ) instanceof Element ) { 1092 element = (Element) nl.item( i ); 1093 String s = element.getNamespaceURI(); 1094 if ( ( s == null && namespace == null ) || ( namespace != null && namespace.equals( s ) ) ) { 1095 if ( element.getLocalName().equals( name ) ) { 1096 childElement = element; 1097 break; 1098 } 1099 } 1100 } 1101 } 1102 } 1103 1104 if ( childElement == null ) { 1105 throw new XMLParsingException( "Required child-element " + name + '(' + namespaceURI + ") of element " 1106 + node.getNodeName() + " is missing." ); 1107 } 1108 1109 return childElement; 1110 } 1111 1112 /** 1113 * Returns the specified child element of the given element. If there is more than one with that 1114 * name, the first one is returned. 1115 * 1116 * @deprecated 1117 * @param name 1118 * name of the child element 1119 * @param namespaceURI 1120 * namespace of the child element 1121 * @param node 1122 * current element 1123 * @return the element or null, if it is missing 1124 * @TODO refactoring required 1125 */ 1126 @Deprecated 1127 public static Element getChildElement( String name, URI namespaceURI, Node node ) { 1128 1129 String namespace = namespaceURI == null ? null : namespaceURI.toString(); 1130 1131 NodeList nl = node.getChildNodes(); 1132 Element element = null; 1133 Element childElement = null; 1134 1135 if ( ( nl != null ) && ( nl.getLength() > 0 ) ) { 1136 for ( int i = 0; i < nl.getLength(); i++ ) { 1137 if ( nl.item( i ) instanceof Element ) { 1138 element = (Element) nl.item( i ); 1139 String s = element.getNamespaceURI(); 1140 if ( ( s == null && namespace == null ) || ( namespace != null && namespace.equals( s ) ) ) { 1141 if ( element.getLocalName().equals( name ) ) { 1142 childElement = element; 1143 break; 1144 } 1145 } 1146 } 1147 } 1148 } 1149 return childElement; 1150 } 1151 1152 /** 1153 * Returns the specified child elements of the given element. 1154 * 1155 * @deprecated 1156 * @param name 1157 * name of the child elements 1158 * @param namespaceURI 1159 * namespaceURI of the child elements 1160 * @param node 1161 * current element 1162 * @return list of matching child elements 1163 */ 1164 @Deprecated 1165 public static ElementList getChildElements( String name, URI namespaceURI, Node node ) { 1166 1167 String namespace = namespaceURI == null ? null : namespaceURI.toString(); 1168 1169 NodeList nl = node.getChildNodes(); 1170 Element element = null; 1171 ElementList elementList = new ElementList(); 1172 1173 if ( ( nl != null ) && ( nl.getLength() > 0 ) ) { 1174 for ( int i = 0; i < nl.getLength(); i++ ) { 1175 if ( nl.item( i ) instanceof Element ) { 1176 element = (Element) nl.item( i ); 1177 1178 String s = element.getNamespaceURI(); 1179 1180 if ( ( s == null && namespace == null ) || ( namespace != null && namespace.equals( s ) ) ) { 1181 if ( element.getLocalName().equals( name ) ) { 1182 elementList.addElement( element ); 1183 } 1184 } 1185 } 1186 } 1187 } 1188 return elementList; 1189 } 1190 1191 /** 1192 * 1193 * Create a new and empty DOM document. 1194 * 1195 * @return a new and empty DOM document. 1196 */ 1197 public static Document create() { 1198 return getDocumentBuilder().newDocument(); 1199 } 1200 1201 /** 1202 * Create a new document builder with: 1203 * <UL> 1204 * <li>namespace awareness = true 1205 * <li>whitespace ignoring = false 1206 * <li>validating = false 1207 * <li>expandind entity references = false 1208 * </UL> 1209 * 1210 * @return new document builder 1211 */ 1212 public static synchronized DocumentBuilder getDocumentBuilder() { 1213 DocumentBuilder builder = null; 1214 try { 1215 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 1216 factory.setNamespaceAware( true ); 1217 factory.setExpandEntityReferences( false ); 1218 factory.setIgnoringElementContentWhitespace( false ); 1219 factory.setValidating( false ); 1220 builder = factory.newDocumentBuilder(); 1221 } catch ( Exception ex ) { 1222 LOG.logError( ex.getMessage(), ex ); 1223 } 1224 return builder; 1225 } 1226 1227 /** 1228 * Returns the specified attribute value of the given node. 1229 * 1230 * @param node 1231 * current element 1232 * @param attrName 1233 * local name of the attribute 1234 * 1235 * @return the value of the attribute or null, if it is missing 1236 * @deprecated use 1237 * @see #getAttrValue(Node, URI, String, String) instead 1238 */ 1239 @Deprecated 1240 public static String getAttrValue( Node node, String attrName ) { 1241 NamedNodeMap atts = node.getAttributes(); 1242 if ( atts == null ) { 1243 return null; 1244 } 1245 Attr a = (Attr) atts.getNamedItem( attrName ); 1246 if ( a != null ) { 1247 return a.getValue(); 1248 } 1249 return null; 1250 } 1251 1252 /** 1253 * Returns the specified attribute value of the given node. 1254 * 1255 * @param node 1256 * current element 1257 * @param namespaceURI 1258 * namespace of the attribute 1259 * @param attrName 1260 * local name of the attribute 1261 * @param defaultVal 1262 * default value to be returned if attribute is nat available 1263 * 1264 * @return the value of the attribute or null, if it is missing 1265 */ 1266 public static String getAttrValue( Node node, URI namespaceURI, String attrName, String defaultVal ) { 1267 String namespace = namespaceURI == null ? null : namespaceURI.toString(); 1268 NamedNodeMap atts = node.getAttributes(); 1269 if ( atts == null ) { 1270 return defaultVal; 1271 } 1272 Attr a = null; 1273 if ( namespace == null ) { 1274 a = (Attr) atts.getNamedItem( attrName ); 1275 } else { 1276 a = (Attr) atts.getNamedItemNS( namespace, attrName ); 1277 } 1278 if ( a != null ) { 1279 return a.getValue(); 1280 } 1281 return defaultVal; 1282 } 1283 1284 /** 1285 * Parses an XML document and returns a DOM object. The underlying input stream is closed at the 1286 * end. 1287 * 1288 * @param reader 1289 * accessing the resource to parse 1290 * @return a DOM object, if en error occurs the response is <code>null</code> 1291 * 1292 * @throws IOException 1293 * @throws SAXException 1294 */ 1295 public static Document parse( Reader reader ) 1296 throws IOException, SAXException { 1297 javax.xml.parsers.DocumentBuilder parser = null; 1298 Document doc = null; 1299 try { 1300 DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance(); 1301 fac.setNamespaceAware( true ); 1302 fac.setValidating( false ); 1303 fac.setIgnoringElementContentWhitespace( false ); 1304 fac.setValidating( false ); 1305 parser = fac.newDocumentBuilder(); 1306 doc = parser.parse( new InputSource( reader ) ); 1307 } catch ( ParserConfigurationException ex ) { 1308 throw new IOException( "Unable to initialize DocumentBuilder: " + ex.getMessage() ); 1309 } catch ( Exception e ) { 1310 throw new SAXException( e.getMessage() ); 1311 } finally { 1312 reader.close(); 1313 } 1314 return doc; 1315 } 1316 1317 /** 1318 * Parses an XML document and returns a DOM object. 1319 * 1320 * @deprecated 1321 * @param is 1322 * accessing the resource to parse 1323 * @return a DOM object 1324 * @throws IOException 1325 * @throws SAXException 1326 */ 1327 @Deprecated 1328 public static Document parse( InputStream is ) 1329 throws IOException, SAXException { 1330 return parse( new InputStreamReader( is ) ); 1331 1332 } 1333 1334 /** 1335 * Copies one node to another node. 1336 * 1337 * @param source 1338 * @param dest 1339 * @return the copied node 1340 */ 1341 public static Node copyNode( Node source, Node dest ) { 1342 if ( source.getNodeType() == Node.TEXT_NODE ) { 1343 Text tn = dest.getOwnerDocument().createTextNode( getStringValue( source ) ); 1344 return tn; 1345 } 1346 NamedNodeMap attr = source.getAttributes(); 1347 if ( attr != null ) { 1348 for ( int i = 0; i < attr.getLength(); i++ ) { 1349 ( (Element) dest ).setAttribute( attr.item( i ).getNodeName(), attr.item( i ).getNodeValue() ); 1350 } 1351 } 1352 NodeList list = source.getChildNodes(); 1353 for ( int i = 0; i < list.getLength(); i++ ) { 1354 if ( !( list.item( i ) instanceof Text ) ) { 1355 if ( !( list.item( i ) instanceof Comment ) ) { 1356 Element en = dest.getOwnerDocument().createElementNS( list.item( i ).getNamespaceURI(), 1357 list.item( i ).getNodeName() ); 1358 if ( list.item( i ).getNodeValue() != null ) { 1359 en.setNodeValue( list.item( i ).getNodeValue() ); 1360 } 1361 Node n = copyNode( list.item( i ), en ); 1362 dest.appendChild( n ); 1363 } 1364 } else if ( ( list.item( i ) instanceof CDATASection ) ) { 1365 CDATASection cd = dest.getOwnerDocument().createCDATASection( list.item( i ).getNodeValue() ); 1366 dest.appendChild( cd ); 1367 } else { 1368 Text tn = dest.getOwnerDocument().createTextNode( list.item( i ).getNodeValue() ); 1369 dest.appendChild( tn ); 1370 } 1371 } 1372 return dest; 1373 } 1374 1375 /** 1376 * Appends a node to an element. 1377 * <p> 1378 * The node can be from the same document or a different one (it is automatically imported, if 1379 * necessary). 1380 * 1381 * @param source 1382 * @param dest 1383 * @return the element that is appended to 1384 */ 1385 public static Node insertNodeInto( Node source, Node dest ) { 1386 // Document dDoc = null; 1387 // Document sDoc = source.getOwnerDocument(); 1388 Node n = dest.getOwnerDocument().importNode( source, true ); 1389 dest.appendChild( n ); 1390 // if ( dest instanceof Document ) { 1391 // dDoc = (Document) dest; 1392 // } else { 1393 // dDoc = dest.getOwnerDocument(); 1394 // } 1395 // if ( dDoc.equals( sDoc ) ) { 1396 // dest.appendChild( source ); 1397 // } else { 1398 // Element element = dDoc.createElementNS( source.getNamespaceURI(), source.getNodeName() ); 1399 // dest.appendChild( element ); 1400 // // FIXME why not use Document.import() here? copyNode seems broken... 1401 // copyNode( source, element ); 1402 // } 1403 return dest; 1404 } 1405 1406 /** 1407 * Returns the first child element of the submitted node. 1408 * 1409 * @param node 1410 * @return the first child element of the submitted node. 1411 */ 1412 public static Element getFirstChildElement( Node node ) { 1413 NodeList nl = node.getChildNodes(); 1414 Element element = null; 1415 if ( ( nl != null ) && ( nl.getLength() > 0 ) ) { 1416 for ( int i = 0; i < nl.getLength(); i++ ) { 1417 if ( nl.item( i ) instanceof Element ) { 1418 element = (Element) nl.item( i ); 1419 break; 1420 } 1421 } 1422 } 1423 return element; 1424 } 1425 1426 /** 1427 * @deprecated Returns the first child element of the submitted node that matches the given 1428 * local name. 1429 * 1430 * @param node 1431 * @param name 1432 * @return the child element 1433 */ 1434 @Deprecated 1435 public static Element getChildElement( Node node, String name ) { 1436 NodeList nl = node.getChildNodes(); 1437 Element element = null; 1438 Element childElement = null; 1439 if ( ( nl != null ) && ( nl.getLength() > 0 ) ) { 1440 for ( int i = 0; i < nl.getLength(); i++ ) { 1441 if ( nl.item( i ) instanceof Element ) { 1442 element = (Element) nl.item( i ); 1443 1444 if ( element.getNodeName().equals( name ) ) { 1445 childElement = element; 1446 1447 break; 1448 } 1449 } 1450 } 1451 } 1452 return childElement; 1453 } 1454 1455 /** 1456 * Returns all child elements of the given node. 1457 * 1458 * @param node 1459 * @return all child elements of the given node. 1460 */ 1461 public static ElementList getChildElements( Node node ) { 1462 NodeList children = node.getChildNodes(); 1463 ElementList list = new ElementList(); 1464 for ( int i = 0; i < children.getLength(); i++ ) { 1465 if ( children.item( i ).getNodeType() == Node.ELEMENT_NODE ) { 1466 list.elements.add( (Element) children.item( i ) ); 1467 } 1468 } 1469 return list; 1470 } 1471 1472 /** 1473 * sets the value of an existing node 1474 * 1475 * @param target 1476 * @param nodeValue 1477 */ 1478 public static void setNodeValue( Element target, String nodeValue ) { 1479 NodeList nl = target.getChildNodes(); 1480 for ( int i = 0; i < nl.getLength(); i++ ) { 1481 target.removeChild( nl.item( i ) ); 1482 } 1483 Text text = target.getOwnerDocument().createTextNode( nodeValue ); 1484 target.appendChild( text ); 1485 } 1486 1487 /** 1488 * Creates a new <code>Element</code> node from the given parameters and appends it to the 1489 * also specified <code>Element</code>. Adds a text node to the newly generated 1490 * <code>Element</code> as well. 1491 * 1492 * @param element 1493 * <code>Element</code> that the new <code>Element</code> is appended to 1494 * @param namespaceURI 1495 * use null for default namespace 1496 * @param name 1497 * qualified name 1498 * @param nodeValue 1499 * value for a text node that is appended to the generated element 1500 * @return the appended <code>Element</code> node 1501 */ 1502 public static Element appendElement( Element element, URI namespaceURI, String name, String nodeValue ) { 1503 String namespace = namespaceURI == null ? null : namespaceURI.toString(); 1504 Element newElement = element.getOwnerDocument().createElementNS( namespace, name ); 1505 if ( nodeValue != null && !nodeValue.equals( "" ) ) 1506 newElement.appendChild( element.getOwnerDocument().createTextNode( nodeValue ) ); 1507 element.appendChild( newElement ); 1508 return newElement; 1509 } 1510 }