<?

/*/
	© 2007 by Locke Enterprises (iLocke.com) - All rights reserved.
	License:  Authorized for use on the [www.AutoGlassHosting.com] websites.
	File:  NXML.phi  [v1.0]
	Purpose:  Three classes to parse and store XML data: XML_tree, XML_node, and XML_parser
	Created:  Nathan - 4/9/2007
	Example: $oXML = new XML_tree( "<xml attribute='value'/>", true );  // debugging is on
	Modification History:
		· 4/12/2007 - Nathan - architected the node.path method and the tree methods for .node/.walk/.seek
		· mm/dd/yyyy - [name] - [comment]
	Examples:
		//$text = "<A><B/><C>level C</C>- level A -<D>la letra 'D'</D></A>";
		//$text = "<test1>testing1 <a href='supertest'>LINK</a> more text <test2><test2a>test2a</test2a><test2b>test2b1</test2b><test2b>test2b2</test2b></test2> ...and here is some MORE [Level1] text <test3 class='final' here=\"&quot;\">testing3</test3> (lastly!) </test1>";
		//$text = "<NagsData><Request><Function>101</Function><Vehicle></Vehicle></Request><Response><TXDate>20070401</TXDate><TXTime>15:18:48</TXTime><CompletedQuery>0</CompletedQuery><ErrorCode>0</ErrorCode><Vehicle><Year>1949</Year><Year>1950</Year><Year>1951</Year><Year>1952</Year><Year>1953</Year><Year>1954</Year><Year>1955</Year><Year>1956</Year><Year>1957</Year><Year>1958</Year><Year>1959</Year><Year>1960</Year><Year>1961</Year><Year>1962</Year><Year>1963</Year><Year>1964</Year><Year>1965</Year><Year>1966</Year><Year>1967</Year><Year>1968</Year><Year>1969</Year><Year>1970</Year><Year>1971</Year><Year>1972</Year><Year>1973</Year><Year>1974</Year><Year>1975</Year><Year>1976</Year><Year>1977</Year><Year>1978</Year><Year>1979</Year><Year>1980</Year><Year>1981</Year><Year>1982</Year><Year>1983</Year><Year>1984</Year><Year>1985</Year><Year>1986</Year><Year>1987</Year><Year>1988</Year><Year>1989</Year><Year>1990</Year><Year>1991</Year><Year>1992</Year><Year>1993</Year><Year>1994</Year><Year>1995</Year><Year>1996</Year><Year>1997</Year><Year>1998</Year><Year>1999</Year><Year>2000</Year><Year>2001</Year><Year>2002</Year><Year>2003</Year><Year>2004</Year><Year>2005</Year><Year>2006</Year><Year>2007</Year><Year>2008</Year></Vehicle></Response></NagsData>";
		$text = "<NagsData><Request><Function>200</Function><Vehicle><Year>1980</Year><Make>Chevrolet</Make><Model>Impala</Model><BodyStyle>2 Door Coupe</BodyStyle><Opening>WS</Opening></Vehicle></Request><Response><TXDate>20070401</TXDate><TXTime>17:07:45</TXTime><CompletedQuery>1</CompletedQuery><ErrorCode>0</ErrorCode><Vehicle><Year>1980</Year><Make>Chevrolet</Make><Model>Impala</Model><BodyStyle>2 Door Coupe</BodyStyle><CRNo>1817</CRNo></Vehicle><Windshield><PartNo>DW00905CLNN</PartNo><Description>Clear</Description><NagsPrice>0</NagsPrice><PriceStatus>NLP</PriceStatus><NagsLabor>2.6</NagsLabor><Hardware><PartNo>WB-1018</PartNo><Description>Blade(2 Wipers)(18\")(Std Style)</Description><MFR>PRECISION</MFR><Price>13.04</Price><PriceStatus>A</PriceStatus><NAGSID>HBB034579</NAGSID></Hardware><Hardware><PartNo>WB-1218</PartNo><Description>Blade(2 Wipers)(18\")(Spoiler Style)</Description><MFR>PRECISION</MFR><Price>14.68</Price><PriceStatus>A</PriceStatus><NAGSID>HBB034580</NAGSID></Hardware><Hardware><PartNo>20211692</PartNo><Description>Moulding(Reveal)</Description><MFR>GM</MFR><RelativeLoc>UP</RelativeLoc><Price>92.2</Price><PriceStatus>A</PriceStatus><NAGSID>HML002748</NAGSID></Hardware><Hardware><PartNo>20211706</PartNo><Description>Moulding(Reveal)</Description><MFR>GM</MFR><Side>R</Side><Price>50.47</Price><PriceStatus>A</PriceStatus><NAGSID>HML002750</NAGSID></Hardware><Hardware><PartNo>20211707</PartNo><Description>Moulding(Reveal)</Description><MFR>GM</MFR><Side>L</Side><Price>50.47</Price><PriceStatus>A</PriceStatus><NAGSID>HML002751</NAGSID></Hardware><Hardware><PartNo>3536254</PartNo><Description>Moulding(Garnish)</Description><MFR>GM</MFR><RelativeLoc>UP</RelativeLoc><Price>22.7</Price><PriceStatus>A</PriceStatus><NAGSID>HML002752</NAGSID></Hardware><Hardware><PartNo>20480626</PartNo><Description>Moulding(Garnish)</Description><MFR>GM</MFR><Side>R</Side><Price>0</Price><PriceStatus>NLP</PriceStatus><NAGSID>HML002753</NAGSID></Hardware><Hardware><PartNo>20480627</PartNo><Description>Moulding(Garnish)</Description><MFR>GM</MFR><Side>L</Side><Price>0</Price><PriceStatus>NLP</PriceStatus><NAGSID>HML002754</NAGSID></Hardware><Hardware><PartNo>10074554</PartNo><Description>Moulding(Garnish)</Description><MFR>GM</MFR><RelativeLoc>LO</RelativeLoc><Side>R</Side><Price>5.9</Price><PriceStatus>A</PriceStatus><NAGSID>HML002755</NAGSID></Hardware><Hardware><PartNo>10074555</PartNo><Description>Moulding(Garnish)</Description><MFR>GM</MFR><RelativeLoc>LO</RelativeLoc><Side>L</Side><Price>7.3</Price><PriceStatus>A</PriceStatus><NAGSID>HML002756</NAGSID></Hardware><Hardware><PartNo>20629060</PartNo><Description>Moulding(Reveal)</Description><MFR>GM</MFR><Side>R</Side><Price>0</Price><PriceStatus>NLP</PriceStatus><NAGSID>HML003190</NAGSID></Hardware><Hardware><PartNo>20629061</PartNo><Description>Moulding(Reveal)</Description><MFR>GM</MFR><Side>L</Side><Price>0</Price><PriceStatus>NLP</PriceStatus><NAGSID>HML003191</NAGSID></Hardware><Hardware><PartNo>20427642</PartNo><Description>Moulding(Reveal)(Pillar)(Drip)</Description><MFR>GM</MFR><Side>R</Side><Price>88.37</Price><PriceStatus>A</PriceStatus><NAGSID>HML003192</NAGSID></Hardware><Hardware><PartNo>20427643</PartNo><Description>Moulding(Reveal)(Pillar)(Drip)</Description><MFR>GM</MFR><Side>L</Side><Price>90.05</Price><PriceStatus>A</PriceStatus><NAGSID>HML003193</NAGSID></Hardware><Hardware><PartNo>3073180</PartNo><Description>Moulding(Reveal)(Pillar)(Belt)</Description><MFR>GM</MFR><Side>R</Side><Price>47</Price><PriceStatus>A</PriceStatus><NAGSID>HML003194</NAGSID></Hardware><Hardware><PartNo>3073181</PartNo><Description>Moulding(Reveal)(Pillar)(Belt)</Description><MFR>GM</MFR><Side>L</Side><Price>49.9</Price><PriceStatus>A</PriceStatus><NAGSID>HML003195</NAGSID></Hardware><Hardware><PartNo>20629058</PartNo><Description>Moulding(Reveal)</Description><MFR>GM</MFR><RelativeLoc>UP</RelativeLoc><Price>0</Price><PriceStatus>NLP</PriceStatus><NAGSID>HML003280</NAGSID></Hardware><Hardware><PartNo>DK107K</PartNo><Description>Moulding</Description><MFR>DNK</MFR><Price>16.58</Price><PriceStatus>A</PriceStatus><NAGSID>HML008464</NAGSID></Hardware><Hardware><PartNo>MPK 1066</PartNo><Description>Moulding</Description><MFR>PRECISION</MFR><Price>12.74</Price><PriceStatus>A</PriceStatus><NAGSID>HML008464</NAGSID></Hardware><Hardware><PartNo>918583</PartNo><Description>Mirror(Rear View)</Description><MFR>GM</MFR><Price>70.1</Price><PriceStatus>A</PriceStatus><NAGSID>HMR000237</NAGSID></Hardware><Kit><PartNo>HAH000004</PartNo><Description>(Urethane,Dam,Primer)</Description><Quantity>2</Quantity><Price>56</Price><PriceStatus>A</PriceStatus></Kit><Kit><PartNo>HAH000448</PartNo><Description>(Fast-Cure Urethane/Dam/Primer)</Description><Quantity>2</Quantity><Price>96</Price><PriceStatus>A</PriceStatus></Kit><OEM><PartNo>20151433</PartNo><Description>Clear</Description><MFR>GM</MFR><Price>392</Price><PriceStatus>A</PriceStatus></OEM><OEM><PartNo>20151435</PartNo><Description>Green Tint/Blue Shade</Description><MFR>GM</MFR><Price>258.62</Price><PriceStatus>A</PriceStatus></OEM></Windshield><Windshield><PartNo>DW00905GBNN</PartNo><Description>Green Tint/Blue Shade</Description><NagsPrice>187.25</NagsPrice><PriceStatus>A</PriceStatus><NagsLabor>2.6</NagsLabor><Hardware><PartNo>WB-1018</PartNo><Description>Blade(2 Wipers)(18\")(Std Style)</Description><MFR>PRECISION</MFR><Price>13.04</Price><PriceStatus>A</PriceStatus><NAGSID>HBB034579</NAGSID></Hardware><Hardware><PartNo>WB-1218</PartNo><Description>Blade(2 Wipers)(18\")(Spoiler Style)</Description><MFR>PRECISION</MFR><Price>14.68</Price><PriceStatus>A</PriceStatus><NAGSID>HBB034580</NAGSID></Hardware><Hardware><PartNo>20211692</PartNo><Description>Moulding(Reveal)</Description><MFR>GM</MFR><RelativeLoc>UP</RelativeLoc><Price>92.2</Price><PriceStatus>A</PriceStatus><NAGSID>HML002748</NAGSID></Hardware><Hardware><PartNo>20211706</PartNo><Description>Moulding(Reveal)</Description><MFR>GM</MFR><Side>R</Side><Price>50.47</Price><PriceStatus>A</PriceStatus><NAGSID>HML002750</NAGSID></Hardware><Hardware><PartNo>20211707</PartNo><Description>Moulding(Reveal)</Description><MFR>GM</MFR><Side>L</Side><Price>50.47</Price><PriceStatus>A</PriceStatus><NAGSID>HML002751</NAGSID></Hardware><Hardware><PartNo>3536254</PartNo><Description>Moulding(Garnish)</Description><MFR>GM</MFR><RelativeLoc>UP</RelativeLoc><Price>22.7</Price><PriceStatus>A</PriceStatus><NAGSID>HML002752</NAGSID></Hardware><Hardware><PartNo>20480626</PartNo><Description>Moulding(Garnish)</Description><MFR>GM</MFR><Side>R</Side><Price>0</Price><PriceStatus>NLP</PriceStatus><NAGSID>HML002753</NAGSID></Hardware><Hardware><PartNo>20480627</PartNo><Description>Moulding(Garnish)</Description><MFR>GM</MFR><Side>L</Side><Price>0</Price><PriceStatus>NLP</PriceStatus><NAGSID>HML002754</NAGSID></Hardware><Hardware><PartNo>10074554</PartNo><Description>Moulding(Garnish)</Description><MFR>GM</MFR><RelativeLoc>LO</RelativeLoc><Side>R</Side><Price>5.9</Price><PriceStatus>A</PriceStatus><NAGSID>HML002755</NAGSID></Hardware><Hardware><PartNo>10074555</PartNo><Description>Moulding(Garnish)</Description><MFR>GM</MFR><RelativeLoc>LO</RelativeLoc><Side>L</Side><Price>7.3</Price><PriceStatus>A</PriceStatus><NAGSID>HML002756</NAGSID></Hardware><Hardware><PartNo>20629060</PartNo><Description>Moulding(Reveal)</Description><MFR>GM</MFR><Side>R</Side><Price>0</Price><PriceStatus>NLP</PriceStatus><NAGSID>HML003190</NAGSID></Hardware><Hardware><PartNo>20629061</PartNo><Description>Moulding(Reveal)</Description><MFR>GM</MFR><Side>L</Side><Price>0</Price><PriceStatus>NLP</PriceStatus><NAGSID>HML003191</NAGSID></Hardware><Hardware><PartNo>20427642</PartNo><Description>Moulding(Reveal)(Pillar)(Drip)</Description><MFR>GM</MFR><Side>R</Side><Price>88.37</Price><PriceStatus>A</PriceStatus><NAGSID>HML003192</NAGSID></Hardware><Hardware><PartNo>20427643</PartNo><Description>Moulding(Reveal)(Pillar)(Drip)</Description><MFR>GM</MFR><Side>L</Side><Price>90.05</Price><PriceStatus>A</PriceStatus><NAGSID>HML003193</NAGSID></Hardware><Hardware><PartNo>3073180</PartNo><Description>Moulding(Reveal)(Pillar)(Belt)</Description><MFR>GM</MFR><Side>R</Side><Price>47</Price><PriceStatus>A</PriceStatus><NAGSID>HML003194</NAGSID></Hardware><Hardware><PartNo>3073181</PartNo><Description>Moulding(Reveal)(Pillar)(Belt)</Description><MFR>GM</MFR><Side>L</Side><Price>49.9</Price><PriceStatus>A</PriceStatus><NAGSID>HML003195</NAGSID></Hardware><Hardware><PartNo>20629058</PartNo><Description>Moulding(Reveal)</Description><MFR>GM</MFR><RelativeLoc>UP</RelativeLoc><Price>0</Price><PriceStatus>NLP</PriceStatus><NAGSID>HML003280</NAGSID></Hardware><Hardware><PartNo>DK107K</PartNo><Description>Moulding</Description><MFR>DNK</MFR><Price>16.58</Price><PriceStatus>A</PriceStatus><NAGSID>HML008464</NAGSID></Hardware><Hardware><PartNo>MPK 1066</PartNo><Description>Moulding</Description><MFR>PRECISION</MFR><Price>12.74</Price><PriceStatus>A</PriceStatus><NAGSID>HML008464</NAGSID></Hardware><Hardware><PartNo>918583</PartNo><Description>Mirror(Rear View)</Description><MFR>GM</MFR><Price>70.1</Price><PriceStatus>A</PriceStatus><NAGSID>HMR000237</NAGSID></Hardware><Kit><PartNo>HAH000004</PartNo><Description>(Urethane,Dam,Primer)</Description><Quantity>2</Quantity><Price>56</Price><PriceStatus>A</PriceStatus></Kit><Kit><PartNo>HAH000448</PartNo><Description>(Fast-Cure Urethane/Dam/Primer)</Description><Quantity>2</Quantity><Price>96</Price><PriceStatus>A</PriceStatus></Kit><OEM><PartNo>20151433</PartNo><Description>Clear</Description><MFR>GM</MFR><Price>392</Price><PriceStatus>A</PriceStatus></OEM><OEM><PartNo>20151435</PartNo><Description>Green Tint/Blue Shade</Description><MFR>GM</MFR><Price>258.62</Price><PriceStatus>A</PriceStatus></OEM></Windshield><Windshield><PartNo>DW00906CLNN</PartNo><Description>Clear</Description><NagsPrice>0</NagsPrice><PriceStatus>NLP</PriceStatus><NagsLabor>2.6</NagsLabor><Hardware><PartNo>WB-1018</PartNo><Description>Blade(2 Wipers)(18\")(Std Style)</Description><MFR>PRECISION</MFR><Price>13.04</Price><PriceStatus>A</PriceStatus><NAGSID>HBB034579</NAGSID></Hardware><Hardware><PartNo>WB-1218</PartNo><Description>Blade(2 Wipers)(18\")(Spoiler Style)</Description><MFR>PRECISION</MFR><Price>14.68</Price><PriceStatus>A</PriceStatus><NAGSID>HBB034580</NAGSID></Hardware><Hardware><PartNo>20211692</PartNo><Description>Moulding(Reveal)</Description><MFR>GM</MFR><RelativeLoc>UP</RelativeLoc><Price>92.2</Price><PriceStatus>A</PriceStatus><NAGSID>HML002748</NAGSID></Hardware><Hardware><PartNo>20211706</PartNo><Description>Moulding(Reveal)</Description><MFR>GM</MFR><Side>R</Side><Price>50.47</Price><PriceStatus>A</PriceStatus><NAGSID>HML002750</NAGSID></Hardware><Hardware><PartNo>20211707</PartNo><Description>Moulding(Reveal)</Description><MFR>GM</MFR><Side>L</Side><Price>50.47</Price><PriceStatus>A</PriceStatus><NAGSID>HML002751</NAGSID></Hardware><Hardware><PartNo>3536254</PartNo><Description>Moulding(Garnish)</Description><MFR>GM</MFR><RelativeLoc>UP</RelativeLoc><Price>22.7</Price><PriceStatus>A</PriceStatus><NAGSID>HML002752</NAGSID></Hardware><Hardware><PartNo>20480626</PartNo><Description>Moulding(Garnish)</Description><MFR>GM</MFR><Side>R</Side><Price>0</Price><PriceStatus>NLP</PriceStatus><NAGSID>HML002753</NAGSID></Hardware><Hardware><PartNo>20480627</PartNo><Description>Moulding(Garnish)</Description><MFR>GM</MFR><Side>L</Side><Price>0</Price><PriceStatus>NLP</PriceStatus><NAGSID>HML002754</NAGSID></Hardware><Hardware><PartNo>10074554</PartNo><Description>Moulding(Garnish)</Description><MFR>GM</MFR><RelativeLoc>LO</RelativeLoc><Side>R</Side><Price>5.9</Price><PriceStatus>A</PriceStatus><NAGSID>HML002755</NAGSID></Hardware><Hardware><PartNo>10074555</PartNo><Description>Moulding(Garnish)</Description><MFR>GM</MFR><RelativeLoc>LO</RelativeLoc><Side>L</Side><Price>7.3</Price><PriceStatus>A</PriceStatus><NAGSID>HML002756</NAGSID></Hardware><Hardware><PartNo>20629060</PartNo><Description>Moulding(Reveal)</Description><MFR>GM</MFR><Side>R</Side><Price>0</Price><PriceStatus>NLP</PriceStatus><NAGSID>HML003190</NAGSID></Hardware><Hardware><PartNo>20629061</PartNo><Description>Moulding(Reveal)</Description><MFR>GM</MFR><Side>L</Side><Price>0</Price><PriceStatus>NLP</PriceStatus><NAGSID>HML003191</NAGSID></Hardware><Hardware><PartNo>20427642</PartNo><Description>Moulding(Reveal)(Pillar)(Drip)</Description><MFR>GM</MFR><Side>R</Side><Price>88.37</Price><PriceStatus>A</PriceStatus><NAGSID>HML003192</NAGSID></Hardware><Hardware><PartNo>20427643</PartNo><Description>Moulding(Reveal)(Pillar)(Drip)</Description><MFR>GM</MFR><Side>L</Side><Price>90.05</Price><PriceStatus>A</PriceStatus><NAGSID>HML003193</NAGSID></Hardware><Hardware><PartNo>3073180</PartNo><Description>Moulding(Reveal)(Pillar)(Belt)</Description><MFR>GM</MFR><Side>R</Side><Price>47</Price><PriceStatus>A</PriceStatus><NAGSID>HML003194</NAGSID></Hardware><Hardware><PartNo>3073181</PartNo><Description>Moulding(Reveal)(Pillar)(Belt)</Description><MFR>GM</MFR><Side>L</Side><Price>49.9</Price><PriceStatus>A</PriceStatus><NAGSID>HML003195</NAGSID></Hardware><Hardware><PartNo>20629058</PartNo><Description>Moulding(Reveal)</Description><MFR>GM</MFR><RelativeLoc>UP</RelativeLoc><Price>0</Price><PriceStatus>NLP</PriceStatus><NAGSID>HML003280</NAGSID></Hardware><Hardware><PartNo>DK107K</PartNo><Description>Moulding</Description><MFR>DNK</MFR><Price>16.58</Price><PriceStatus>A</PriceStatus><NAGSID>HML008464</NAGSID></Hardware><Hardware><PartNo>MPK 1066</PartNo><Description>Moulding</Description><MFR>PRECISION</MFR><Price>12.74</Price><PriceStatus>A</PriceStatus><NAGSID>HML008464</NAGSID></Hardware><Hardware><PartNo>918583</PartNo><Description>Mirror(Rear View)</Description><MFR>GM</MFR><Price>70.1</Price><PriceStatus>A</PriceStatus><NAGSID>HMR000237</NAGSID></Hardware><Kit><PartNo>HAH000004</PartNo><Description>(Urethane,Dam,Primer)</Description><Quantity>2</Quantity><Price>56</Price><PriceStatus>A</PriceStatus></Kit><Kit><PartNo>HAH000448</PartNo><Description>(Fast-Cure Urethane/Dam/Primer)</Description><Quantity>2</Quantity><Price>96</Price><PriceStatus>A</PriceStatus></Kit><OEM><PartNo>20151432</PartNo><Description>Clear</Description><MFR>GM</MFR><Price>227.21</Price><PriceStatus>A</PriceStatus></OEM><OEM><PartNo>20151434</PartNo><Description>Green Tint/Blue Shade</Description><MFR>GM</MFR><Price>227.21</Price><PriceStatus>A</PriceStatus></OEM></Windshield><Windshield><PartNo>DW00906GBNN</PartNo><Description>Green Tint/Blue Shade</Description><NagsPrice>186.5</NagsPrice><PriceStatus>A</PriceStatus><NagsLabor>2.6</NagsLabor><Hardware><PartNo>WB-1018</PartNo><Description>Blade(2 Wipers)(18\")(Std Style)</Description><MFR>PRECISION</MFR><Price>13.04</Price><PriceStatus>A</PriceStatus><NAGSID>HBB034579</NAGSID></Hardware><Hardware><PartNo>WB-1218</PartNo><Description>Blade(2 Wipers)(18\")(Spoiler Style)</Description><MFR>PRECISION</MFR><Price>14.68</Price><PriceStatus>A</PriceStatus><NAGSID>HBB034580</NAGSID></Hardware><Hardware><PartNo>20211692</PartNo><Description>Moulding(Reveal)</Description><MFR>GM</MFR><RelativeLoc>UP</RelativeLoc><Price>92.2</Price><PriceStatus>A</PriceStatus><NAGSID>HML002748</NAGSID></Hardware><Hardware><PartNo>20211706</PartNo><Description>Moulding(Reveal)</Description><MFR>GM</MFR><Side>R</Side><Price>50.47</Price><PriceStatus>A</PriceStatus><NAGSID>HML002750</NAGSID></Hardware><Hardware><PartNo>20211707</PartNo><Description>Moulding(Reveal)</Description><MFR>GM</MFR><Side>L</Side><Price>50.47</Price><PriceStatus>A</PriceStatus><NAGSID>HML002751</NAGSID></Hardware><Hardware><PartNo>3536254</PartNo><Description>Moulding(Garnish)</Description><MFR>GM</MFR><RelativeLoc>UP</RelativeLoc><Price>22.7</Price><PriceStatus>A</PriceStatus><NAGSID>HML002752</NAGSID></Hardware><Hardware><PartNo>20480626</PartNo><Description>Moulding(Garnish)</Description><MFR>GM</MFR><Side>R</Side><Price>0</Price><PriceStatus>NLP</PriceStatus><NAGSID>HML002753</NAGSID></Hardware><Hardware><PartNo>20480627</PartNo><Description>Moulding(Garnish)</Description><MFR>GM</MFR><Side>L</Side><Price>0</Price><PriceStatus>NLP</PriceStatus><NAGSID>HML002754</NAGSID></Hardware><Hardware><PartNo>10074554</PartNo><Description>Moulding(Garnish)</Description><MFR>GM</MFR><RelativeLoc>LO</RelativeLoc><Side>R</Side><Price>5.9</Price><PriceStatus>A</PriceStatus><NAGSID>HML002755</NAGSID></Hardware><Hardware><PartNo>10074555</PartNo><Description>Moulding(Garnish)</Description><MFR>GM</MFR><RelativeLoc>LO</RelativeLoc><Side>L</Side><Price>7.3</Price><PriceStatus>A</PriceStatus><NAGSID>HML002756</NAGSID></Hardware><Hardware><PartNo>20629060</PartNo><Description>Moulding(Reveal)</Description><MFR>GM</MFR><Side>R</Side><Price>0</Price><PriceStatus>NLP</PriceStatus><NAGSID>HML003190</NAGSID></Hardware><Hardware><PartNo>20629061</PartNo><Description>Moulding(Reveal)</Description><MFR>GM</MFR><Side>L</Side><Price>0</Price><PriceStatus>NLP</PriceStatus><NAGSID>HML003191</NAGSID></Hardware><Hardware><PartNo>20427642</PartNo><Description>Moulding(Reveal)(Pillar)(Drip)</Description><MFR>GM</MFR><Side>R</Side><Price>88.37</Price><PriceStatus>A</PriceStatus><NAGSID>HML003192</NAGSID></Hardware><Hardware><PartNo>20427643</PartNo><Description>Moulding(Reveal)(Pillar)(Drip)</Description><MFR>GM</MFR><Side>L</Side><Price>90.05</Price><PriceStatus>A</PriceStatus><NAGSID>HML003193</NAGSID></Hardware><Hardware><PartNo>3073180</PartNo><Description>Moulding(Reveal)(Pillar)(Belt)</Description><MFR>GM</MFR><Side>R</Side><Price>47</Price><PriceStatus>A</PriceStatus><NAGSID>HML003194</NAGSID></Hardware><Hardware><PartNo>3073181</PartNo><Description>Moulding(Reveal)(Pillar)(Belt)</Description><MFR>GM</MFR><Side>L</Side><Price>49.9</Price><PriceStatus>A</PriceStatus><NAGSID>HML003195</NAGSID></Hardware><Hardware><PartNo>20629058</PartNo><Description>Moulding(Reveal)</Description><MFR>GM</MFR><RelativeLoc>UP</RelativeLoc><Price>0</Price><PriceStatus>NLP</PriceStatus><NAGSID>HML003280</NAGSID></Hardware><Hardware><PartNo>DK107K</PartNo><Description>Moulding</Description><MFR>DNK</MFR><Price>16.58</Price><PriceStatus>A</PriceStatus><NAGSID>HML008464</NAGSID></Hardware><Hardware><PartNo>MPK 1066</PartNo><Description>Moulding</Description><MFR>PRECISION</MFR><Price>12.74</Price><PriceStatus>A</PriceStatus><NAGSID>HML008464</NAGSID></Hardware><Hardware><PartNo>918583</PartNo><Description>Mirror(Rear View)</Description><MFR>GM</MFR><Price>70.1</Price><PriceStatus>A</PriceStatus><NAGSID>HMR000237</NAGSID></Hardware><Kit><PartNo>HAH000004</PartNo><Description>(Urethane,Dam,Primer)</Description><Quantity>2</Quantity><Price>56</Price><PriceStatus>A</PriceStatus></Kit><Kit><PartNo>HAH000448</PartNo><Description>(Fast-Cure Urethane/Dam/Primer)</Description><Quantity>2</Quantity><Price>96</Price><PriceStatus>A</PriceStatus></Kit><OEM><PartNo>20151432</PartNo><Description>Clear</Description><MFR>GM</MFR><Price>227.21</Price><PriceStatus>A</PriceStatus></OEM><OEM><PartNo>20151434</PartNo><Description>Green Tint/Blue Shade</Description><MFR>GM</MFR><Price>227.21</Price><PriceStatus>A</PriceStatus></OEM></Windshield></Response></NagsData>";
		echo "<blockquote>".htmlspecialchars($text)."</blockquote>";
		$oXML = new XML_tree( &$text );
		$oXML->display();
/*/


/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/


//-------------------------------------------------------------------------
// XML_tree:  Data storage and routines for handling of XML. Uses the separate XML_parser object and a list of the XML_node obkects.
//-------------------------------------------------------------------------
class XML_tree {

	var $maxID = 0;
	var $topnode = null;
	var $directory = null;
	var $position = null;  // current building or traversal site
	var $parser = null;
	var $bDebugging = false;
	var $filter = null;
	var $filterLevels = null;
	var $filterMatches = null;


//-------------------------------------------------------------------------
// Constructor; automatically performs the parse on the specified xml data.
//-------------------------------------------------------------------------
function XML_tree( $data, $debugging=false ) {

	/// initz...
	$this->bDebugging = $debugging;
	$this->directory = array();
	$newID = $this->add( "_TOP", null, "!" );
	$this->topnode =& $this->directory[$newID];
	
	/// autoparse if data was passed in...
	if( $data != "" ) $this->parse( &$data );
	
	/// debug printouts...
	if( $this->bDebugging ) {
		echo "<hr>";
		$oXML->enumerate();
		echo "<hr>\n";
		$oXML->display();
	}
	
} // XML_tree()


//-------------------------------------------------------------------------
// parse:  Merely instantiate the parser which automatically does the xml parsing.
//-------------------------------------------------------------------------
function parse( $data, $debugging=false ) {

	$this->parser = new XML_parser( &$this, &$data, ($this->bDebugging || $debugging) );
	$this->parser = null;

} // parse()


//-------------------------------------------------------------------------
// add:  Puts another node into the tree.
//-------------------------------------------------------------------------
function add( $name, $attributes=null, $text="" ) {
	
	$this->maxID++;  // increment this
	$oNode = new XML_node( &$this, $name, $attributes, $text, $this->position );  // the created node points back up to the current position
	$oNode->ID = $this->maxID;
	$this->directory[$this->maxID] =& $oNode;  // the new node is put at the end of the directory
	if( $this->position > 0 ) {
		$this->directory[$this->position]->children[] = $this->maxID;
	} elseif( $this->bDebugging && $this->maxID > 1 ) {
		echo "tree.add [error] no position at '".$name."'<br>\n";
	}
	$this->position = $this->maxID; // move the pointer to the new node for a new 'current' position
	if( $this->bDebugging ) echo $this->directory[$this->position]->name.":".$this->maxID."<br>\n";
	
	return $this->maxID;

} // add()


//-------------------------------------------------------------------------
// append:  Add text onto a node.
//-------------------------------------------------------------------------
function append( $text, $position=0 ) {
	
	if( $position==0 ) $position = $this->position;
	$this->directory[$position]->text .= $text;

} // append()


//-------------------------------------------------------------------------
// closenode:  Moves the position for the next add up one level.
//-------------------------------------------------------------------------
function closenode() {
	
	if( $this->bDebugging ) echo "(closenode:".$this->position.":".$this->directory[$this->position]->parent.":".$this->directory[$this->directory[$this->position]->parent]->name.")";
	
	if( $this->position > 0 && $this->directory[$this->position]->parent > 0 ) {
		$this->position = $this->directory[$this->position]->parent;
	} elseif( $this->bDebugging ) echo "(null)";

} // closenode()


//-------------------------------------------------------------------------
// node:  Quick locator function; returns a reference to the node with the specified ID.
//-------------------------------------------------------------------------
function & node( $ID=null ) {
	
	if( (!isset($ID) || intval($ID)<1) && $this->position > 0 ) $ID = $this->position;
	//echo "tree.node: [".$ID."]<br>\n";
	return isset($this->directory[$ID]) ? $this->directory[$ID] : null;

} // node()


//-------------------------------------------------------------------------
// resetWalk:  Resets the walk.
//-------------------------------------------------------------------------
function resetWalk() {

	$this->position = 1;
	for( $i=1; $i<=$this->maxID; $i++ ) {
		$this->directory[$i]->walkChild = -1;
	}
	$this->filter = "";
	$this->filterLevels = array();
	$this->filterMatches = array();
	
} // resetWalk()


//-------------------------------------------------------------------------
// walkNext:  Walks to the next node in the tree and returns a reference to that node.
//-------------------------------------------------------------------------
function & walkNext() {

	$bVerboseDebug = false;
	
	/// get the next child node if possible...
	if( $bVerboseDebug ) echo "<blockquote style='margin-top: 0; margin-bottom: 0; padding-top: 0; padding-bottom: 0;'>";
	$currentNode =& $this->directory[$this->position];
	if( $this->bDebugging ) echo "walkNext: starting at: ".$this->position." | ".$currentNode->ID."<br>\n";
	if( $bVerboseDebug ) echo "trying the children of '".$currentNode->name."' (".count($currentNode->children).")...<br>\n";
	if( count($currentNode->children) > 0 ) {
		if( ++$currentNode->walkChild < count($currentNode->children) ) {
			$currentNode =& $this->directory[$currentNode->children[$currentNode->walkChild]];
			$this->position = $currentNode->ID;
			if( $this->bDebugging ) echo "walkNext: returning currentNode.ID = ".$currentNode->ID."<br>\n";
			if( $bVerboseDebug ) echo "-- Returning: ".$currentNode->name."</blockquote>\n";
			return $currentNode;
		}
	}
	if( $bVerboseDebug ) echo "...couldn't find any eligible children of '".$currentNode->name."'<br>\n";
	if( $this->bDebugging ) echo "walkNext: no eligible children, moving up...<br>\n";
	
	/// go to the parent and go to the next child node from there...
	$i = 0;
	while( $currentNode->ID != $this->topnode->ID ) {
		if( ++$i > 50 ) return null;
		$currentNode =& $this->directory[$this->directory[$currentNode->ID]->parent];
		$bKeepGoing = $currentNode->walkChild < count($currentNode->children);
		if( $bVerboseDebug ) echo "     ".$i." | ".$currentNode->ID." : ".$currentNode->name." [".$currentNode->walkChild." / ".count($currentNode->children)."] &nbsp; {".($bKeepGoing === true)."}<br>\n";
		if( (count($currentNode->children) > 0) && ($currentNode->walkChild < count($currentNode->children)) ) {
			if( ++$currentNode->walkChild < count($currentNode->children) ) {
				$currentNode =& $currentNode->oTree->directory[$currentNode->children[$currentNode->walkChild]];
				$this->position = $currentNode->ID;
				if( $bVerboseDebug ) echo "-- returning: ".$currentNode->name." = '".$currentNode->text."'<br>\n";
				if( $bVerboseDebug ) echo "</blockquote>";
				return $currentNode;
			}
		}
	}
	if( $bVerboseDebug ) echo "-- returning NULL &nbsp; (".$currentNode->walkChild." / ".count($currentNode->children).")<br>\n";
	if( $bVerboseDebug ) echo "</blockquote>";
	$this->filter = null;  // reset this if we were running a seek
	return null;

} // walkNext()


//-------------------------------------------------------------------------
// seek:  Walks through the tree while seeking for the next node matching the specified tag name filter.
//-------------------------------------------------------------------------
function & seek( $path=null, $bCaseSensitive=false, $bDebugging=false ) {

	/// initz...
	if( !isset($path) ) $path = "";
	if( $bDebugging ) echo $path."<br>\n";
	$bCaseSensitive = ($bCaseSensitive === true);

	/// when we need to reset the seek/walk...
	if( !isset($this->filter) || $path != $this->filter ) {
		if( $bDebugging ) echo "tree.seek: resetWalk<br>\n";
		$this->resetWalk();
		$this->filter = $path;
		$this->filterLevels = split( "/", $this->filter );
		$this->filterMatches = array();
		for( $i=0; $i<count($this->filterLevels); $i++ ) $this->filterMatches[$i] = false;
		$this->position = $this->topnode->ID;
		if( $bDebugging ) echo "tree.seek: position = '".$this->position."'<br>\n";
	}

	/// walk to the next matching path...
	$oNode =& $this->walkNext();
	if( $bDebugging ) echo "tree.seek: [".$oNode->ID."] ".$oNode->name."<br>\n";
	$i = 0;  // sanity check
	while( (++$i < 999)  &&  ($oNode != null)  &&  ( $path=="" || ($bCaseSensitive && ($oNode->path() != $path)) || (strtolower($oNode->path()) != strtolower($path)) ) ) {
		$oNode =& $this->walkNext();
	}
	if( $bDebugging ) echo "tree.seek: ".$i." iterations<br>\n";
	return $oNode;

} // seek()


//-------------------------------------------------------------------------
// display:  Print out the data contents in each node of our XML tree.
//-------------------------------------------------------------------------
function display() {

	/// bail if we have nothing to display...
	if( !isset($this->topnode) ) {
		if( $this->bDebugging ) echo "TOPNODE NOT SET!";
		return;
	}
	if( count($this->topnode->children) < 1 ) {
		if( $this->bDebugging ) echo "NO NODES IN THE TREE TO DISPLAY!";
		return;
	}
	
	/// display each of the children - each will recurse to its children as necessary...
	echo "[tree.display] There is/are (".count($this->topnode->children).") child/ren of the _top node.<br>\n";
	for( $i=0; $i<count($this->topnode->children); $i++ ) {
		$this->directory[$this->topnode->children[$i]]->display();
	}

} // display()


//-------------------------------------------------------------------------
// enumerate:  Print out a simple enumerated version of the directory.
//-------------------------------------------------------------------------
function enumerate() {

	/// loop through each item in the directory; don't recurse display the node childrens...
	echo "<blockqutoe style='color: #808080; background: #FCFCE0;'>";
	foreach( $this->directory as $ID => $oNode ) {
		echo "ID ".$ID.": ".$oNode->name." = ".$oNode->text." &nbsp; (parent=".$oNode->parent.") &nbsp; [children:".count($oNode->children)."]<br>\n";
	}
	echo "</blockqutoe>";

} // enumerate()


} // XML_tree class


/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/


///-------------------------------------------------------------------------
class XML_node {

	var $oTree = null;
	var $ID = 0;
	var $name = "";
	var $text = "";
	var $attributes = null;
	var $children = null;
	var $parent = 0;
	var $walkChild = -1;
	var $bDebugging = false;


//-------------------------------------------------------------------------
// Constructor. Can automatically assign text and/or attributes.
//-------------------------------------------------------------------------
function XML_node( &$oTree, $name, $attributes=null, $text="", $parent=0, $debugging=false ) {

	$this->oTree = &$oTree;
	$this->name = $name;
	if( isset($attributes) ) if( is_array($attributes) ) $this->attributes = &$attributes;
	if( !isset($this->attributes) ) $this->attributes = array();
	if( $text != "" ) $this->text = &$text;
	if( intval($parent) > 0 ) $this->parent = intval($parent);
	$this->bDebugging = ($debugging === true);
	$this->children = array();

} // XML_node()


//-------------------------------------------------------------------------
// path: Return the path to this node - recursing into parent nodes. (prepends a /slash, but leaves no trailing slash/)
//-------------------------------------------------------------------------
function path( $bFull=false ) {

	if( $this->parent > 0 ) { // get the parent's path as well
		$oParent =& $this->oTree->directory[$this->parent];
		$path = $oParent->path($bFull) . "/" . $this->name;
	} elseif( $bFull ) {  // except we only want to return the _top node when specifically requested
		$path = "/" . $this->name;
	}
	return $path;

} // path()


//-------------------------------------------------------------------------
// display:  Print out the data in our node. Recurse into and call displayal of data in any child nodes.
//-------------------------------------------------------------------------
function display( $level=0, $showChildren=true ) {

	if( $level < 1 ) echo "Tree class = '".get_class($this->oTree)."' - counting the _TOP node, there are (<b>".count($this->oTree->directory)."</b>) items in the directory.<br>\n";
	echo "<b>".$this->name."</b> [ID:".$this->ID."] = ".$this->text."\n";
	if( $showChildren && count($this->children)>0 ) {
		echo "<blockquote style='margin-top: 0; margin-bottom: 0; padding-top: 0; padding-bottom: 0;'>";
		for( $i=0; $i<count($this->children); $i++ ) {
			$this->oTree->directory[$this->children[$i]]->display( $level+1 );
		}
		echo "</blockquote>";
	} else echo "<br>\n";

} // display()


} // XML_node class


/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/


//-------------------------------------------------------------------------
// XML_parser:  This class works closely with the tree container to load in nodes from the data specified.
//-------------------------------------------------------------------------
class XML_parser {

	var $parser = null;
	var $errorNum = null;
	var $errorMsg = null;
	var $oTree = null;
	var $bDebugging = false;


//-------------------------------------------------------------------------
// Constructor. Automatically parses data and loads it into the specified tree.
//-------------------------------------------------------------------------
function XML_parser( &$oTree, $data, $debugging=false ) {

	$this->oTree =& $oTree;
	$this->bDebugging = $debugging;
	$this->parse( &$data );

} // XML_parser()


//-------------------------------------------------------------------------
// parse:  Main worker routine. Uses the class object tag_* callbacks below.
//-------------------------------------------------------------------------
function parse( $data ) {

	$this->parser = xml_parser_create('UTF-8');
	xml_set_object( $this->parser, $this );
	xml_parser_set_option( $this->parser, XML_OPTION_SKIP_WHITE, 1 );
	xml_parser_set_option( $this->parser, XML_OPTION_CASE_FOLDING, 0 );
	xml_set_element_handler($this->parser, 'tag_open', 'tag_close');
	xml_set_character_data_handler( $this->parser, 'tag_data' );
	if( !xml_parse($this->parser, $data) ) {
		$this->errorNum = xml_get_error_code($this->parser);
		$this->errorMsg = xml_error_string($this->errorNum);
		$this->errorMsg .= "<br>\nLine: ".xml_get_current_line_number($this->parser)." &nbsp;|&nbsp; Column: ".xml_get_current_column_number($this->parser)."<br>\n";
		if( $this->bDebugging ) echo $this->errorMsg;
	}
	xml_parser_free($this->parser);

} // parse()


///-------------------------------------------------------------------------
function tag_open( $parser, $tag, $attribs ) {

	if( $this->bDebugging ) echo "OPENING:&nbsp; <b>".$tag."</b><br>\n";
	$this->oTree->add( $tag, $attribs );  // automatically moves the position to the new node

} // tag_open()


///-------------------------------------------------------------------------
function tag_data( $parser, $text ) {

	if( $this->bDebugging ) echo "tag_data: ".$this->oTree->position . " / " . $text . "<br>\n";
	$this->oTree->append( &$text );

} // tag_data()


///-------------------------------------------------------------------------
function tag_close( $parser, $tag ) {

	if( $this->bDebugging ) echo "CLOSING:&nbsp; <b>/".$tag."</b><br>\n";
	$this->oTree->closenode();

} // tag_close()


} // XML_parser class


?>