0

I am trying to build a XPath Query Builder in order to have a generic code as portable as possible.

So far, this is what I came up with :

private static string XpathQueryBuilder (string NodeName,string AttributeName = null, string AttributeValue = null)
    {

        string XpathAttr = "";

        if (AttributeName != null)
            if (AttributeValue != null)
                XpathAttr = "[@" + AttributeName + "='" + AttributeValue + "']";
            else
                XpathAttr = "[@" + AttributeName + "='*']";
        return "//" + NodeName + XpathAttr;

    }    

The problem I see with this method though is that if I have more than one attribute or node that I would like to look for, this function won't work. Is there a way to create an XPath Query dynamically that could theorically accept any number of attributes and/or Nodes.

My priority is on having a function that accepts more than one attribute and attribute value as this is the more likely case than more than one node.

Thank you for your time!

2
  • Why not pass a KeyValuePair<string,string>, pass a list and loop through it by appending the attributes? Commented Apr 22, 2016 at 14:45
  • That would be a good easy alternative instead of creating a custome Linq provider. I wasn't aware of the Key Pair mechanism. Thank you. Commented Apr 22, 2016 at 14:49

3 Answers 3

2

You can use Dictionary<string,string> to make the function capable of receiving multiple attributes parameter :

private static string XpathQueryBuilder(string nodeName, Dictionary<string,string> attributes = null)
{
    string xpathAttr = "";
    if (attributes != null)
    {
        xpathAttr = 
            "[" + 
            String.Join(" and ", 
                    attributes.Select(o => 
                    {
                        var attrVal = o.Value ?? "*";
                        return "@" + o.Key + "='" + attrVal + "'";
                    })
            ) + "]";
    }

    return "//" + nodeName + xpathAttr;
}   

example usage :

var node = "Root";
var attrs = new Dictionary<string, string>
{
    {"foo", "bar"},
    {"baz", null},  
};
var result = XpathQueryBuilder(node, attrs);
Console.WriteLine(result);

dotnetfiddle demo

output :

//Root[@foo='bar' and @baz='*']
Sign up to request clarification or add additional context in comments.

Comments

1

You can use LINQ to XML.

It will allow you select any data that you want.

Also, if you need more generic solution, you can try to implement your own LINQ Provider for that.

The second way is more complicated than the first one, but as a result you will have more generic solution that will provide access to your xml file by LINQ chains and expressions (lambda etc).

A few links with examples for help:

http://weblogs.asp.net/mehfuzh/writing-custom-linq-provider

http://fairwaytech.com/2013/03/writing-a-custom-linq-provider-with-re-linq/

http://jacopretorius.net/2010/01/implementing-a-custom-linq-provider.html

https://aashishkoirala.wordpress.com/2014/03/10/linq-provider-1/

2 Comments

Thank you for the links, I will definitely look into LINQ to XML library, but for now, it feels a little bit over what I feel I can manage so I'll go with the dictionnary method.
Sure, I'm not forcing you to jump into in right now. And I will be glad to help you with understating LINQ to XML. Or if you decided to implement your own provider - feel free to ask about it!
1

Have you tried using LINQ to XML?

using System.Linq;
using System.Xml;
using System.Xml.Linq;

String GUID = "something";

XElement profilesXel = XElement.Load("your xml file path");
XElement currProfile = (from el in profilesXel
                        where (String)el.Element("GUID") == GUID
                        select el).First();

....

1 Comment

Could you be more specific in your answer? I am having a hard time trying to figure this out and I must be honest, I don't know where to begin in the Linq library.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.