View Javadoc

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              // start at opening tag, search starting from end of start tag
73              possEndIndex = pXML.indexOf( pEndTag, endStartVal );
74              // look for a new start tag to see if embedded tag w/ same name
75              newStartIndex = pXML.indexOf( pStartTag, startVal );
76              // set where next search will take place from
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 }