views:

2005

answers:

3

Hello, I'm trying to search multiple attributes in XML :

<APIS>
  <API Key="00001">
    <field Username="username1" UserPassword="password1" FileName="Filename1.xml"/>
    <field Username="username2" UserPassword="password2" FileName="Filename2.xml"/>
    <field Username="username3" UserPassword="password3" FileName="Filename3.xml"/>
  </API>
</APIS>

I need to check if in the "field" the Username AND UserPassword values are both what I am comparing with my Dataset values, is there a way where I can check multiple attributes (AND condition) without writing my own logic of using Flags and breaking out of loops.

Is there a built in function of XMLDoc that does it? Any help would be appreciated!

Thanks in advance.

+2  A: 

Searching XML is what XPath was made for. You didn't specify what language you're using, but here's an article on processing XML using XPath in Java, and here's one using C#.

Bill the Lizard
+4  A: 

To search for what you want in the snippet of XML you provided, you would need the following XPath expression:

/APIS/API/field[@Username='username1' and @UserPassword='password1']

This would either return something, if user name and password match - or not if they don't.

Of couse the XPath expression is just a string - you can build it dynamically with values that were entered into a form field, for example.

If you tell what language/environment you are in, code samples posted here will likely get more specific.

This is a way to do it in C# (VB.NET is analogous):

// make sure the following line is included in your class
using System.Xml;

XmlDocument xmldoc = new XmlDocument();
xmldoc.Load("your XML string or file");

string xpath = "/APIS/API/field[@Username='{0}' and @UserPassword='{1}']";
string username = "username1";
string password = "password1";

xpath = String.Format(xpath, username, password);
XmlNode userNode = xmldoc.SelectSingleNode(xpath);

if (userNode != null)
{
  // found something with given user name and password
}
else
{
  // username or password incorrect
}

Be aware that neither user names nor passwords can contain single quotes, or the above example will fail. Here is some info on this peculiarity.

There is also a How-To from Microsoft available: HOW TO: Use the System.Xml.XmlDocument Class to Execute XPath Queries in Visual C# .NET

Tomalak
+1  A: 

This is a FAQ about XPath expressions.

One or more XPath expressions (whose evaluated type is boolean), can be connected together using the boolean operators "and" and "or" and using the XPath function not().

Do note that the names of these are all in lower case. XPath is case-sensitive and a any other capitalization of these names (such as "AND") will not be recognized as the name of the logical operators.

So, in this particular case, the wanted XPath expression will be something as the following:

/*/*/field[@Username = your-ds-username and @UserPassword = your-ds-UserPassword]

where your-ds-username and your-ds-UserPassword should be substituted with the respective values you want to use from the dataset.

Dimitre Novatchev
Why do use "/*/*" (as opposed to "//")? I thought - when you are unspecific about the element names, you could just as well be unspecific about nesting depth. Or do I overlook something?
Tomalak
@Tomalak: Avoid the "//" abbreviation as it causes the complete document tree to be searched. When we know the structure of the document we can specify only the necessary levels and names. In this case the names are the only name occuring at a level, so it is more efficient not to check for a name
Dimitre Novatchev