1 package com.flexiblewebsolutions.xml.util;
2
3 import java.util.ArrayList;
4 import java.util.Iterator;
5
6 import com.flexiblewebsolutions.util.ListUtils;
7
8 /***
9 * Pulls values from an xml file using a simple XML parser.
10 *
11 * @author Donavon Buss
12 */
13 public class XMLStringParser
14 {
15 /***
16 * Return the value for a single tag inside a xml block.
17 *
18 * @param pString -
19 * XML string.
20 * @param pTag -
21 * Name of tag to retrieve value for
22 * @return Value of tag
23 */
24 public static String getValueForTag( StringBuffer pString, String pTag )
25 {
26 String startTag = "<" + pTag;
27 String endTag = "</" + pTag + ">";
28
29 String returnVal = null;
30 int startIndex = pString.indexOf( startTag );
31 if( startIndex != -1 )
32 {
33 int endStartTag = pString.indexOf( ">", startIndex );
34 startTag = pString.substring( startIndex, endStartTag + 1 );
35
36 String fullTag = getEntireTag( pString, startIndex, endTag,
37 startTag );
38
39 returnVal = fullTag.substring( startTag.length(), fullTag.length()
40 - endTag.length() );
41 returnVal = ( removeTabChars( new StringBuffer( returnVal ) ) ).toString();
42 }
43 return ( returnVal );
44 }
45
46 /***
47 * Retreive entire xml tag, ignoring embedded ending tags with same name
48 *
49 * @param pXML
50 * XML String
51 * @param pStartIndex
52 * Location in XML to begin looking for tag.
53 * @param pEndTag
54 * Ending Tag
55 * @param pStartTag
56 * Starting XML tag
57 * @return Entire XML tag including start and end tag
58 */
59 public static String getEntireTag( StringBuffer pXML, int pStartIndex,
60 String pEndTag, String pStartTag )
61 {
62 StringBuffer xml = removeNewlines( pXML );
63
64 int startVal = pStartIndex + pStartTag.length();
65 int endStartVal = pStartIndex + pStartTag.length();
66 String tag = null;
67
68 int possEndIndex = -1;
69 int newStartIndex = -1;
70 do
71 {
72
73 possEndIndex = pXML.indexOf( pEndTag, endStartVal );
74
75 newStartIndex = pXML.indexOf( pStartTag, startVal );
76
77 endStartVal = possEndIndex + pEndTag.length();
78 startVal = newStartIndex + pStartTag.length();
79 }
80 while( ( newStartIndex != -1 ) && ( possEndIndex > newStartIndex ) );
81
82 tag = pXML.substring( pStartIndex, possEndIndex + pEndTag.length() );
83 return ( tag );
84 }
85
86 /***
87 * Retreive entire xml tag, ignoring embedded ending tags with same name.
88 * End tag is determined.
89 *
90 * @param pXML
91 * XML String
92 * @param pStartIndex
93 * Location in XML to begin looking for tag.
94 * @param pStartTag
95 * Starting XML tag
96 * @return Entire XML tag including start and end tag
97 */
98 public static String getEntireTag( StringBuffer pXML, int pStartIndex,
99 String pStartTag )
100 {
101 StringBuffer tempEndTag = new StringBuffer( pStartTag );
102 tempEndTag.insert( 1, "/" );
103 String endTag = tempEndTag.toString();
104
105 return ( getEntireTag( pXML, pStartIndex, endTag, pStartTag ) );
106 }
107
108 /***
109 * Remove tab characters from input
110 * @param pXML XMl String
111 * @return StringBuffer that has tab characters removed
112 */
113 private static StringBuffer removeTabChars( StringBuffer pXML )
114 {
115 return( removeCharacter( pXML, '\t' ) );
116 }
117
118 /***
119 * Remove new line characters from the xml string if they exist
120 *
121 * @param pXML
122 * Xml String
123 * @return XML String where new lines have been removed.
124 */
125 private static StringBuffer removeNewlines( StringBuffer pXML )
126 {
127 return( removeCharacter( pXML, '\n' ) );
128 }
129
130 /***
131 * Removes a character from the screen
132 * @param pXML Xml String
133 * @param pChar Character to remove
134 * @return Xml String that is free from offending character
135 */
136 private static StringBuffer removeCharacter( StringBuffer pXML, char pChar )
137 {
138 StringBuffer returnXML = new StringBuffer();
139 for( int i = 0; i < pXML.length(); i++ )
140 {
141 if( pXML.charAt( i ) != pChar )
142 {
143 returnXML.append( pXML.charAt( i ) );
144 }
145 }
146 return ( returnXML );
147 }
148
149 /***
150 * Retrieves the tags nested within the top level of the XML string matching a tag name.
151 *
152 * @param pXmlString XML string containing values.
153 * @param pTag Name of tag to find values for.
154 * @return Array of Tag values.
155 */
156 public static String[] getMatchingNestedTags( String pXmlString, String pTag )
157 {
158 ArrayList nestedVals = getNestedTags( pXmlString );
159 String startTag = "<" + pTag + ">";
160 String endTag = "</" + pTag + ">";
161
162 ArrayList returnVals = new ArrayList();
163 for( Iterator it = nestedVals.iterator(); it.hasNext(); )
164 {
165 String tag = (String) it.next();
166 if( tag.startsWith( startTag ) )
167 {
168 returnVals.add( tag );
169 }
170 }
171
172 return ListUtils.convertToStringArray( returnVals );
173 }
174
175 /***
176 * Retrieves all tags nested within the top level of the XML string.
177 *
178 * @param pXmlString XML string containing values.
179 * @return ArrayList of Tag Values.
180 */
181 private static ArrayList getNestedTags( String pXmlString )
182 {
183 StringBuffer xmlContents = removeNewlines( new StringBuffer( pXmlString ) );
184 ArrayList nestedVals = new ArrayList();
185
186 while( xmlContents.length() > 0 )
187 {
188 String thisStartTag = xmlContents.substring( 0,
189 xmlContents.indexOf( ">" ) + 1 );
190 String firstEntry = getEntireTag( xmlContents, 0, thisStartTag );
191 xmlContents.delete( 0, firstEntry.length() );
192 nestedVals.add( firstEntry );
193 }
194
195 return ( nestedVals );
196 }
197
198 /***
199 * Retrieves all tags nested within the tol level of the XML string.
200 *
201 * @param pXmlString XML string containing values
202 * @return String array of tag values.
203 */
204 public static String[] getAllNestedTags( String pXmlString )
205 {
206 ArrayList nestedTags = getNestedTags( pXmlString );
207 return ListUtils.convertToStringArray( nestedTags );
208 }
209 }