001 /*
002 * $Id: XmlUtil.java,v 1.5 2012/02/19 17:35:52 davep Exp $
003 *
004 * This file is part of McIDAS-V
005 *
006 * Copyright 2007-2012
007 * Space Science and Engineering Center (SSEC)
008 * University of Wisconsin - Madison
009 * 1225 W. Dayton Street, Madison, WI 53706, USA
010 * https://www.ssec.wisc.edu/mcidas
011 *
012 * All Rights Reserved
013 *
014 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
015 * some McIDAS-V source code is based on IDV and VisAD source code.
016 *
017 * McIDAS-V is free software; you can redistribute it and/or modify
018 * it under the terms of the GNU Lesser Public License as published by
019 * the Free Software Foundation; either version 3 of the License, or
020 * (at your option) any later version.
021 *
022 * McIDAS-V is distributed in the hope that it will be useful,
023 * but WITHOUT ANY WARRANTY; without even the implied warranty of
024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
025 * GNU Lesser Public License for more details.
026 *
027 * You should have received a copy of the GNU Lesser Public License
028 * along with this program. If not, see http://www.gnu.org/licenses.
029 */
030
031 package edu.wisc.ssec.mcidasv.util;
032
033 import java.util.ArrayList;
034 import java.util.List;
035
036 import org.w3c.dom.Attr;
037 import org.w3c.dom.Element;
038 import org.w3c.dom.NamedNodeMap;
039 import org.w3c.dom.Node;
040 import org.w3c.dom.NodeList;
041
042 /**
043 * A collection of utilities for XML..
044 *
045 */
046 public abstract class XmlUtil extends ucar.unidata.xml.XmlUtil {
047
048 /**
049 * Print all the attributes of the given node
050 *
051 * @param parent
052 */
053 public static void printNode(Node parent) {
054 if (parent==null) {
055 System.out.println("null node!");
056 return;
057 }
058 System.out.println(parent.getNodeName() + " node:");
059 NamedNodeMap attrs = parent.getAttributes();
060 for(int i = 0 ; i<attrs.getLength() ; i++) {
061 Attr attribute = (Attr)attrs.item(i);
062 System.out.println(" " + attribute.getName()+" = "+attribute.getValue());
063 }
064 }
065
066 /**
067 * Find all of the descendant elements of the given parent Node
068 * whose tag name.equals the given tag.
069 *
070 * @param parent The root of the xml dom tree to search.
071 * @param tag The tag name to match.
072 * @return The list of descendants that match the given tag.
073 */
074 public static List<String> findDescendantNamesWithSeparator(Node parent, String tag, String separator) {
075 List<String> found = new ArrayList<String>();
076 findDescendantNamesWithSeparator(parent, tag, "", separator, found);
077 return found;
078 }
079
080 /**
081 * Find all of the descendant elements of the given parent Node
082 * whose tag name equals the given tag.
083 *
084 * @param parent The root of the xml dom tree to search.
085 * @param tag The tag name to match.
086 * @param found The list of descendants that match the given tag.
087 */
088 private static void findDescendantNamesWithSeparator(Node parent, String tag, String descendants, String separator, List<String> found) {
089 if (parent instanceof Element) {
090 String elementName = ((Element)parent).getAttribute("name");
091 if (!elementName.isEmpty()) {
092 descendants += ((Element)parent).getAttribute("name");
093 }
094 if (parent.getNodeName().equals(tag)) {
095 found.add(descendants);
096 }
097 if (!elementName.isEmpty()) {
098 descendants += separator;
099 }
100 }
101 NodeList children = parent.getChildNodes();
102 for (int i = 0; i < children.getLength(); i++) {
103 Node child = children.item(i);
104 findDescendantNamesWithSeparator(child, tag, descendants, separator, found);
105 }
106 }
107
108 /**
109 * Find the element described by nameList (path)
110 *
111 * @param parent
112 * @param nameList
113 * @return
114 */
115 public static Element getElementAtNamedPath(Node parent, List<String>nameList) {
116 return getMakeElementAtNamedPath(parent, nameList, "", false);
117 }
118
119 /**
120 * Make the element described by nameList (path)
121 *
122 * @param parent
123 * @param nameList
124 * @return
125 */
126 public static Element makeElementAtNamedPath(Node parent, List<String>nameList, String tagname) {
127 return getMakeElementAtNamedPath(parent, nameList, tagname, true);
128 }
129
130 /**
131 * Find the element described by nameList (path)
132 *
133 * @param parent
134 * @param nameList
135 * @return
136 */
137 public static Element getMakeElementAtNamedPath(Node parent, List<String> nameList, String tagName, boolean makeNew) {
138 Element thisElement = null;
139 if (parent instanceof Element && !nameList.isEmpty()) {
140 for (int i=0; i < nameList.size(); i++) {
141 String thisName = nameList.get(i);
142 NodeList children = parent.getChildNodes();
143 boolean foundChild = false;
144 for (int j=0; j < children.getLength(); j++) {
145 Node child = children.item(j);
146 if (!(child instanceof Element)) continue;
147 if (XmlUtil.getAttribute(child, "name").equals(thisName)) {
148 if (i == nameList.size()-1) thisElement = (Element)child;
149 parent = child;
150 foundChild = true;
151 break;
152 }
153 }
154
155 // Didn't find it where we expected to. Create a new one.
156 if (makeNew && !foundChild && parent instanceof Element) {
157 try {
158 Element newElement = XmlUtil.create(tagName, (Element)parent);
159 newElement.setAttribute("name", thisName);
160 parent.appendChild(newElement);
161 parent = newElement;
162 thisElement = newElement;
163 } catch (Exception ex) {
164 System.err.println("Error making new " + tagName + " node named " + thisName);
165 break;
166 }
167 }
168 }
169 }
170 return thisElement;
171 }
172 }