How to Auto-Increment an Unique ID in XML

In some cases you will need to create unique ID's for each node in your xml file. For example just think of something like an employee xml file. Let say your xml file looks like this (In the xml example, I assume that there will be always a person id.).

<?xml version="1.0" encoding="ISO-8859-1"?>
  <employee>
   <person id="1">
     <firstname>Bob</firstname> 
     <lastname>Jones</lastname> 
   </person>
   <person id="2"> 
     <firstname>Bob</firstname> 
     <lastname>Jones</lastname>
   </person>
</employee>

And now you would like to create a function which returns the next ID for the person, which should be 3 in our case. For that purpose I wrote a small function which reads the total nodes and incremenets it with one. The function looks like this:

private int GetNextNodeID()
{
    XmlDocument doc = new XmlDocument();
    doc.Load(Server.MapPath("employee.xml"));
    XmlNodeList nodes = doc.SelectNodes("//employee/person");

    int nNodeID = nodes.Count;
    nNodeID++;

    return nNodeID;
}

Sonu

Comments

# Anon said:


That looks incredibly unsafe to me for 2 reasons.

1 - If there is no user id 1 for instance, the count of elements in 1 (which has an id of 2) and then you will try to set the next id as 2 (the number of elements + 1). BANG.

2 - What if the Xml file changes from another thread in between you loading it and getting the number of nodes?

Friday, May 14, 2004 8:19 AM
# Sonu Kapoor said:

Anon,

Thanks for your suggestion.

1.) In my example I assume that there will be ALWAYS a user id.
2.) That is a reasonable point. And I guess that either the user has to lock the xml or check that somebody isn't working on that while using the function.

Sonu

Friday, May 14, 2004 8:22 AM
# Chris McKenzie said:

What if the first user id is 32,667?
Presumably, you could use a seed value for your count, but that raises another question. What if the items in the XML file are not sorted by id? In other words, what if you have a sequence like this (7,5,3,8,9,10,1234,67) where the list is sorted by some other criterion, or where items have been removed from the list?

Friday, May 14, 2004 9:41 AM
# Anon said:

1.) In my example I assume that there will be ALWAYS a user id.

That's a fairly big assumption which no doubt probably involves some effort in keeping it consistent. I know this is only an example but would you not feel more comfortable if it worked either way - I know it'd let me sleep better at night ;)

2.) That is a reasonable point. And I guess that either the user has to lock the xml or check that somebody isn't working on that while using the function.

Maybe you can fix this by using either a Monitor or a different Load() method in the XmlDocument class. Like the one that takes a stream ..

new FileStream(String, FileMode.Open, FileAccess.ReadWrite, FileShare.None), which will stop anyone reading the file until we close it again - say when we have already re-written the new value ? This does mean another thread would have to sit and spin for a bit though :(

Oh and while I am being picky, incremenets should be increments. :) :) I'm not really being picky BTW, I'm just trying to help.

Friday, May 14, 2004 9:46 AM
# Sonu Kapoor said:

There are many "what...if" questions and it is the best to work with that as a beginning. This is just a small snippet of how it could be. Obviously each xml file looks different and not all xml files looks like above shown. The function will only work if you use it with the xml file I provided or a similar one. For everthing else you will need a workaround.

Sonu

Friday, May 14, 2004 9:49 AM
# Sonu Kapoor said:

Anon, of course I would feel much better if I could create a common increment function which works with all kind of xml files. I will consider your comment to the 2nd point and will write some code which monitors the xml file.

>Oh and while I am being picky, incremenets should be increments. :) :) I'm not >really being picky BTW, I'm just trying to help.

Dont worry about that. I appreciate your help. Thats the way how we all can learn from each other ;)

Sonu

Friday, May 14, 2004 9:51 AM
# Anon said:


On point one, how about just doing the following which will admittedly be slower but potentially safer (sorry about the formatting and commenting - haven't memorised the Xml namespace yet :) ). Yes this code *might* leaves holes in the numbers, and still needs locking, but hey :)

XmlDocument doc = new XmlDocument();
doc.Load(Server.MapPath("employee.xml"));
XmlNodeList nodes = doc.SelectNodes("//employee/person");

int maxId = 0;

foreach( XmlNode node in nodes )
{
// get the id attribute
// compare against maxId ...
// Set this maxId to this one if this one is bigger.
}

return maxId + 1;

Friday, May 14, 2004 10:00 AM
# Sonu Kapoor said:

Anon, what is the difference between your code and mine ? Where is the advantage if we use yours ?

Sonu

Friday, May 14, 2004 10:03 AM
# Anon said:


In my code the numbers do not have to be sequential, that is if there are gaps in the numbers ... say it goes 1,2,5,6,7,8 it will not break by trying to create user ID 7, it will instead create user ID 9.

Friday, May 14, 2004 10:40 AM
# Sonu Kapoor said:

Ah..Ok I understand. Yes sure it can work like this.

Sonu

Friday, May 14, 2004 10:44 AM
# Michael Hensen said:

That would be the best option as it is unsafe now .. what.. if you delete number 2. The next new number woud be 3 but there is already a 3.. so the last option of the maxid +1 is the best on..

Friday, May 14, 2004 11:07 AM
# Sonu Kapoor said:

Good point Michael ! Though the best would be not to delete any elements, instead it would be better to set them to "not active" or something like that. That way the increment will work.

Sonu

Friday, May 14, 2004 11:14 AM
# Sonu Kapoor said:

I guess the best would be to update or to create a new function which does all that what we discussed by now. I will do that as soon as I have some time.

Sonu

Friday, May 14, 2004 11:36 AM
# Clint said:

If you know the last person is always the highest id you can use this xpath:

//employee/person[last()]

No looping to find the highest ID and no need to get a nodelist at all.

- Clint

Friday, May 14, 2004 2:34 PM
# Sonu Kapoor said:

Thanks Clint.

Sonu

Friday, May 14, 2004 2:35 PM
# TrackBack said:
Friday, May 14, 2004 3:02 PM
# TrackBack said:
Friday, May 14, 2004 7:08 PM
# Sonu Kapoor said:

Please continue the discussion in Part II of this post !

Sonu

Saturday, May 15, 2004 3:56 PM
# Oleg Tkachenko said:

The most effective solution would be to extend XmlDocument with such functionality.
You can create function GetLastID() and return internally stored value. You can increment this value internally (and within a lock) when new person element is added.

Sunday, May 16, 2004 5:34 AM
# TrackBack said:
Saturday, June 26, 2004 11:40 PM
# wholesale clothing said:

I agree with Chris. I am also looking for the same, but lot of things which has to be considered.

Monday, March 22, 2010 2:04 PM
# Markie said:

Michael Hensen, yeh i thought i was the only one that saw that gapping flaw in this example!

this is not practical at all and should be discouraged,...  i shouldn’t have to change my program and keep data i don’t need just because of a flawed implementation! its the other way around....

Monday, April 26, 2010 10:42 PM
# new ipad accessories said:

It's great to be great , but it's greater to be human.

-----------------------------------

Sunday, December 19, 2010 7:57 PM
# best ipad case said:

-----------------------------------------------------------

You manufactured some very good points there. I believe a investigation on the subject and located most people today will agree with your blog site.

Sunday, January 02, 2011 10:19 PM
# ipad app said:

-----------------------------------------------------------

I like to have a break during the my day and browse by means of some blogs to see what others are saying. This weblog appeared in my search and I couldn't help  but clicking on it. I'm glad I did because it was a very enjoyable read.

Friday, January 07, 2011 10:41 PM
# insignia tv reviews said:

"Excellent data right here. This interesting post created me smile. Maybe should you throw inside a few of pictures it will make the whole thing more intriguing.  In any case, in my language, there are not much very good source such as this."

--------------------------------------------------------------------  

I have a <a href="onlytopreviews.com/">video camera reviews</a> Website,i love him.Mania !You are welcome to look!

Sunday, January 16, 2011 7:58 PM
# Gala Creitz said:

Hey, I just hopped over to your website via StumbleUpon. Not somthing I would commonly read, but I liked your thoughts none the much less. Thanks for making something worth reading.

Monday, July 04, 2011 11:07 PM
# John said:

What if you want to delete a node then add a new in between?

Sunday, November 20, 2011 3:49 AM
# saad said:

Yes sure it can work like this.

Sunday, January 08, 2012 7:14 PM

Leave a Comment

(required) 
(required) 
(optional)
(required)