2016-04-22 2 views
0

Я пытаюсь создать XPath Query Builder, чтобы иметь общий код как можно более портативный.C# XML - XPath Query Builder - динамическое создание запроса

До сих пор, это то, что я придумал:

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; 

    }  

Проблема я вижу, с помощью этого метода, однако, что если у меня есть более чем один атрибут или узел, который я хотел бы посмотреть на это функция не будет работать. Есть ли способ создать XPath-запрос динамически, который теоретически может принимать любое количество атрибутов и/или узлов.

Мой приоритет заключается в наличии функции, которая принимает более одного атрибута и значения атрибута, поскольку это более вероятный случай, чем несколько узлов.

Благодарим вас за внимание!

+0

Почему бы не передать KeyValuePair , передать список и пропустить его, добавив атрибуты? – james31rock

+0

Это было бы неплохой альтернативой вместо создания провайдера Linust custome. Я не знал о механизме Key Pair. Спасибо. –

ответ

2

Вы можете использовать Dictionary<string,string>, чтобы функция способна принимать несколько параметров атрибутов :

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; 
} 

пример использования:

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

dotnetfiddle demo

выход:

//Root[@foo='bar' and @baz='*'] 
+0

Работает чудесно для того, что мне нужно, спасибо. –

1

Вы пытались использовать 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(); 

....

+0

Не могли бы вы быть более конкретными в своем ответе? Мне тяжело пытаться понять это, и я должен быть честным, я не знаю, с чего начать в библиотеке Linq. –

+0

Я обновил свой ответ, надеюсь, что это поможет –

+0

Спасибо за обновление. –

1

Вы можете использовать LINQ to XML.

Это позволит вам выбрать любые данные, которые вы хотите.

Кроме того, если вам нужно более общее решение, вы можете попробовать реализовать your own LINQ Provider.

Второй способ более сложный, чем первый, но в результате у вас будет более общее решение, обеспечивающее доступ к вашему XML-файлу с помощью цепочек и выражений LINQ (lambda и т. Д.).

Несколько ссылок с примерами для помощи:

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/

+0

Благодарим вас за ссылки, я определенно займусь библиотекой LINQ to XML, но пока чувствую себя немного над тем, что, как я чувствую, могу справиться, поэтому я пойду с помощью метода dictionnary. –

+0

Конечно, я не заставляю вас прыгать прямо сейчас. И я буду рад помочь вам с преуменьшением LINQ to XML. Или, если вы решили реализовать собственный провайдер, не стесняйтесь спрашивать об этом! – MaKCbIMKo

Смежные вопросы