| 
 | 
 | 
 
Home » U++ Library support » U++ Core » how to check specific end tag in a xml file? 
	
		
		
			| how to check specific end tag in a xml file? [message #35785] | 
			Wed, 21 March 2012 11:57   | 
		 
		
			
				
				
				
					
						  
						ayana
						 Messages: 16 Registered: November 2011 
						
					 | 
					Promising Member  | 
					 | 
		 
		 
	 | 
 
	
		Hi All, 
 
How to check for a specific end tag in the large XML file while parsing it? 
 
Suppose the file is, 
 
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 
 
<!DOCTYPE AddressBook> 
 
<AddressBook> 
 
	<person> 
 
		<name>qw</name> 
 
		<surname>we</surname> 
 
		<address>we</address> 
 
		<email>er</email> 
 
	</person> 
 
	<person> 
 
		<name>rer</name> 
 
		<surname>ty</surname> 
 
		<address>ui</address> 
 
		<email>io</email> 
 
	</person> 
 
	<person> 
 
		<name>oo</name> 
 
		<surname>jlj</surname> 
 
		<address>bh</address> 
 
		<email>cft</email> 
 
	</person> 
 
</AddressBook> 
 
The user enters a name in an edit field of GUI, if the name entered matches with the gathered text of 'name tag' the corresponding person details should get add to XMLTree.  
 
For Example: 
            while(! p.End) 
            { 
                 
              if ( p.Tag ( "person" ))  
                  
               { 
 
                if ( p.Tag ( "person" ))  
 
                 { 
	                                                                                          if ( p.Tag ( "name" ) ) 
							 
                   { 
 
                   if( editfield.name==p.ReadText()) 
                                                                                                       { 
                         Add that "<person> to </person>" details to XmlTree 
                       } 
 
 
                   } 
 
                 
                 } 
 
 
              } 
 
 
            } 
 
 
 
Thanks in Advance, 
 
 
-Ayana 
 
 
 
  
		
		
		
 |  
	| 
		
	 | 
 
 
 |  
	| 
		
 |  
	
		
		
			| Re: how to check specific end tag in a xml file? [message #35802 is a reply to message #35785] | 
			Thu, 22 March 2012 10:45    | 
		 
		
			
				
				
				
					
						  
						Sender Ghost
						 Messages: 301 Registered: November 2008 
						
					 | 
					Senior Member  | 
					 | 
		 
		 
	 | 
 
	
		Hello, Ayana. 
 
| ayana wrote on Wed, 21 March 2012 11:57 |   How to check for a specific end tag in the large XML file while parsing it? 
  |  
  
| ayana wrote on Wed, 21 March 2012 11:57 |   The user enters a name in an edit field of GUI, if the name entered matches with the gathered text of 'name tag' the corresponding person details should get add to XMLTree. 
  |  
  
There is XML reference example about methods to parse XML files with XmlParser and XmlNode. As well as AddressBookXML and AddressBookXML2 examples. 
 
I will show you following source code about how to search "name" tag for specified names and changing found "person" data, using XmlNode: 
Toggle Spoiler
#include <Core/Core.h>
using namespace Upp;
#define TAG_AddressBook "AddressBook"
#define TAG_person "person"
#define TAG_name "name"
#define TAG_surname "surname"
#define TAG_address "address"
#define TAG_email "email"
String PrintData(const XmlNode& node) {
	const XmlNode& ls = node[0];
	StringBuffer text;
	for (int i = 0, n = ls.GetCount(); i < n; ++i) {
		const XmlNode& ll = ls[i];
		if (ll.IsTag(TAG_person)) {
			text << "- Person:\n";
			const XmlNode& lname = ll[TAG_name];
			if (!lname.IsVoid())
				text << TAG_name << ": " << lname[0].GetText() << '\n';
			const XmlNode& lsurname = ll[TAG_surname];
			if (!lsurname.IsVoid())
				text << TAG_surname << ": " << lsurname[0].GetText() << '\n';
			const XmlNode& laddress = ll[TAG_address];
			if (!laddress.IsVoid())
				text << TAG_address << ": " << laddress[0].GetText() << '\n';
			const XmlNode& lemail = ll[TAG_email];
			if (!lemail.IsVoid())
				text << TAG_email << ": " << lemail[0].GetText() << '\n';
			text << '\n';
		}
	}
	return text;
}
void ChangeXmlText(XmlNode& node, const char *tag, const String& txt) {
	int q = node.FindTag(tag);
	if (q < 0)	// Adding new tag in case of not found
		node.Add(tag).AddText(txt);
	else		// Changing found tag
		node.At(q).At(0).CreateText(txt);
}
CONSOLE_APP_MAIN
{
	const Vector<String>& cmdLine = CommandLine();
	if (cmdLine.GetCount() == 0) {
		Cout() << "Specify XML file to load\n";
		return;
	}
	String fileName(NormalizePath(cmdLine[0]));
	// Loading contents of file to String
	const String data = LoadFile(fileName);
	if (data.IsVoid()) {
		Cout() << "Error, while loading '" << NormalizePath(fileName) << "' file\n";
		SetExitCode(1);
		return;
	}
	XmlNode node;
	try { // Trying to parse XML file
		node = ParseXML(data);
	}
	catch (XmlError e) {
		Cout() << "XmlError " << e << '\n';
		SetExitCode(1);
		return;
	}
	if (node.GetCount() == 0 || node[0].GetTag() != TAG_AddressBook) {
		Cout() << "There is no following tag for XML file: " << TAG_AddressBook << '\n';
		return;
	}
	Cout() << "Existing data:\n" << PrintData(node);
	// The names of persons for changing data
	const String names[] = { "qw", "rer", "new name" };
	const String text("*"); // some changed data
	// Selecting contents of "AddressBook" tag
	XmlNode& ls = node.At(0);
	for (int j = 0, m = __countof(names); j < m; ++j) { // Iterate through names array
		bool found = false;
		for (int i = 0, n = ls.GetCount(); i < n; ++i) { // Iterate through "AddressBook" tags
			XmlNode& ll = ls.At(i);
			if (ll.IsTag(TAG_person)) { // Checking for "person" tag
				int q = ll.FindTag(TAG_name);
				if (q < 0)
					continue;
				// Selecting contents of "name" tag
				XmlNode& lname = ll.At(q).At(0);
				if (lname.GetText() == names[j]) { // Comparing names
					found = true;
					// Changing contents of "person" tag
					lname.CreateText(String().Cat() << names[j] << " *");
					ChangeXmlText(ll, TAG_surname, text);
					ChangeXmlText(ll, TAG_address, text);
					ChangeXmlText(ll, TAG_email, text);
					break; // in case of no duplicates
				}
			}
		}
		if (!found) { // Adding new "person" tag with their contents, if name not found
			XmlNode& ll = ls.Add(TAG_person);
			ll.Add(TAG_name).AddText(names[j]);
			ll.Add(TAG_surname).AddText(text);
			ll.Add(TAG_address).AddText(text);
			ll.Add(TAG_email).AddText(text);
		}
	}
	Cout() << "Changed data:\n" << PrintData(node);
	fileName = AppendFileName(GetFileDirectory(fileName),
		String().Cat() << GetFileTitle(fileName) << " (changed)" << GetFileExt(fileName));
	// Saving changed XmlNode(s) to different file path
	if (SaveFile(fileName, AsXML(node)))
		Cout() << "Changed file '" << fileName << "' written successfully\n";
	else
		Cout() << "Error, while writing '" << fileName << "' file\n";
}
 
   
With following XML file: 
Toggle Spoiler
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE AddressBook>
<AddressBook>
	<person>
		<name>qw</name>
		<surname>we</surname>
		<address>we</address>
		<email>er</email>
	</person>
	<person>
		<name>rer</name>
		<surname>ty</surname>
		<address>ui</address>
		<email>io</email>
	</person>
	<person>
		<name>oo</name>
		<surname>jlj</surname>
		<address>bh</address>
		<email>cft</email>
	</person>
</AddressBook>
 
   
You will get following output: 
Toggle Spoiler
Existing data:
- Person:
name: qw
surname: we
address: we
email: er
- Person:
name: rer
surname: ty
address: ui
email: io
- Person:
name: oo
surname: jlj
address: bh
email: cft
Changed data:
- Person:
name: qw *
surname: *
address: *
email: *
- Person:
name: rer *
surname: *
address: *
email: *
- Person:
name: oo
surname: jlj
address: bh
email: cft
- Person:
name: new name
surname: *
address: *
email: *
Changed file 'C:\AddressBook (changed).xml' written successfully
 
   
and changed XML file: 
Toggle Spoiler
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE AddressBook>
<AddressBook>
	<person>
		<name>qw *</name>
		<surname>*</surname>
		<address>*</address>
		<email>*</email>
	</person>
	<person>
		<name>rer *</name>
		<surname>*</surname>
		<address>*</address>
		<email>*</email>
	</person>
	<person>
		<name>oo</name>
		<surname>jlj</surname>
		<address>bh</address>
		<email>cft</email>
	</person>
	<person>
		<name>new name</name>
		<surname>*</surname>
		<address>*</address>
		<email>*</email>
	</person>
</AddressBook>
 
  
		
		
		[Updated on: Thu, 22 March 2012 12:46] Report message to a moderator  
 |  
	| 
		
	 | 
 
 
 |  
	| 
		
 |  
	| 
		
 |  
	
		
		
			| Re: how to check specific end tag in a xml file? [message #35839 is a reply to message #35829] | 
			Tue, 27 March 2012 17:37   | 
		 
		
			
				
				
				
					
						  
						Sender Ghost
						 Messages: 301 Registered: November 2008 
						
					 | 
					Senior Member  | 
					 | 
		 
		 
	 | 
 
	
		| ayana wrote on Tue, 27 March 2012 06:49 |   But, I want to save each person to person tag details into individual XML files in the name of "gathered text of 'name' tag".
  |  
  
| ayana wrote on Tue, 27 March 2012 13:22 |   Please help me to accomplish above task.
  |  
  
What you asked for is already inside examples. This is general examples, which not adapted for your specific case, of course. 
 
There is following source code to accomplish your task (in some way): 
#include <Core/Core.h>
using namespace Upp;
CONSOLE_APP_MAIN
{
	const Vector<String>& cmdLine = CommandLine();
	if (cmdLine.GetCount() == 0) {
		Cout() << "Specify XML file to load\n";
		return;
	}
	String fileName(NormalizePath(cmdLine[0]));
	XmlNode node;
	{
		// Loading contents of file to String
		const String data = LoadFile(fileName);
		if (data.IsVoid()) {
			Cerr() << "Error, while loading '" << NormalizePath(fileName) << "' file\n";
			SetExitCode(1);
			return;
		}
	
		try { // Trying to parse XML data
			node = ParseXML(data);
		}
		catch (XmlError e) {
			Cerr() << "XmlError: " << e << '\n';
			SetExitCode(1);
			return;
		}
	}
	const XmlNode& linput = node["Xml"]["InputDataInformation"];
	if (linput.IsVoid()) {
		Cerr() << "There is no Xml/InputDataInformation tag\n";
		SetExitCode(1);
		return;
	}
	const String outputPath = "output";
	if (!DirectoryExists(outputPath))
		if (!RealizeDirectory(outputPath)) {
			Cerr() << "Error while creating '" << outputPath << "' directory\n";
			SetExitCode(1);
			return;
		}
	for (int i = 0, n = linput.GetCount(); i < n; ++i) {
		const XmlNode& linfo = linput[i];
		if (!linfo.IsTag("Information"))
			continue;
		const XmlNode& lname = linfo["Name"];
		if (linfo.IsVoid())
			continue;
		const String name = lname[0].GetText();
		if (name.IsEmpty()) {
			Cerr() << "Empty name for " << i << " tag\n";
			continue;
		}
		const String outputFile = AppendFileName(outputPath, name + ".xml");
		if (!SaveFile(outputFile, AsXML(linfo, XML_HEADER))) {
			Cerr() << "Error, while saving '" << outputFile << "' file\n";
			SetExitCode(1);
			return;
		}
	}
}
 
 
Also, you could find full package (with correct input XML file) inside attachment archive.
		
	- 
	
 
	Attachment: SplitXml.zip
	 
	(Size: 1.84KB, Downloaded 288 times)
 
 
		
		
 |  
	| 
		
	 | 
 
 
 |   
Goto Forum:
 
 Current Time: Tue Nov 04 06:45:15 CET 2025 
 Total time taken to generate the page: 0.03991 seconds 
 |   
 |  
  |