Лучший способ извлечь атрибуты из элементов xml, используя C # /. Net 3.5 - PullRequest
0 голосов
/ 26 июля 2011

Если у нас есть XML вроде:

<Data>
    <Cars>
      <Details>
        <Dataset se-datafilter="cars" dv-datamanipulationrequired="false" dv-filtercondition="" dv-sortcolumn="" dv-gettopNrows="" />
        <XmlData></XmlData>
      </Details>
    </Cars>
    <Jeeps>
      <Details>
        <Dataset se-datafilter="jeeps" dv-datamanipulationrequired="false" dv-filtercondition="" dv-sortcolumn="" dv-gettopNrows="" />
        <XmlData></XmlData>
      </Details>
    </Jeeps>
</Data>

Каков наилучший способ получить значения всех атрибутов, хранящихся в элементе <Dataset> для sMainTagName.sMainTagName может иметь значение «Cars» или «Jeep».Передано из пользовательского интерфейса.

У меня есть следующий код:

var cols = doc.XPathSelectElements("/Data/" + sMainTagName + "/Details");

string sDataFilter = String.Empty;
string sFilterCondition = String.Empty;
string sSortCol = String.Empty;                        

foreach (var att in cols.Elements("Dataset").Attributes())
{                           
    switch(att.Name.ToString())
    {
        case "se-datafilter":
            sDataFilter = att.Value;
            break;
        case "dv-filtercondition":
            sFilterCondition = att.Value;
            break;
        case "dv-sortcolumn":
            sSortCol = att.Value;
            break;
    }
}

Ответы [ 4 ]

3 голосов
/ 26 июля 2011

Я фанат Linq to Xml.Вот пример:

static void Main(string[] args)
    {
        var rawXml =
            @"<Data>
    <Cars>
      <Details>
        <Dataset se-datafilter=""cars"" dv-datamanipulationrequired=""false"" dv-filtercondition="""" dv-sortcolumn="""" dv-gettopNrows="""" />
        <XmlData></XmlData>
      </Details>
    </Cars>
    <Jeeps>
      <Details>
        <Dataset se-datafilter=""jeeps"" dv-datamanipulationrequired=""false"" dv-filtercondition="""" dv-sortcolumn="""" dv-gettopNrows="""" />
        <XmlData></XmlData>
      </Details>
    </Jeeps>
</Data>
";

        var xDoc = XDocument.Parse(rawXml);

        var filterName = "jeeps";
        var attrs = xDoc.Descendants("Dataset").Where(
            x => string.Equals(x.Attribute("se-datafilter").Value,
                 filterName,
                 StringComparison.CurrentCultureIgnoreCase
        ))
        .Attributes();

        foreach (var attr in attrs)
        {
            Console.WriteLine(attr.Value);
        }
    }
}
2 голосов
/ 26 июля 2011

Лично я бы не использовал XPath для начала.Я бы сделал что-то вроде этого:

// Note - if an element in this chain doesn't exist, you'll get a
// NullReferenceException
var details = doc.Element("Data")
                 .Element(mainTagName)
                 .Element("Details")
                 .Element("Dataset");

string dataFilter = ((string) details.Attribute("se-datafilter")) ?? "";
string filterCondition= ((string) details.Attribute("dv-filtercondition")) ?? "";
string sortCol = ((string) details.Attribute("dv-sortcolumn")) ?? "";

(кстати, я предполагаю, что есть только один элемент набора данных);

При этом используется тот факт, что явное преобразование строки изXAttribute вернет ноль, если атрибут не существует (т.е. вы вызываете его по нулевой ссылке).

2 голосов
/ 26 июля 2011

Как насчет возврата словаря, построенного из атрибутов.

return xdoc.XPathSelectElements("/Data/" + sMainTagName + "/Details/Dataset")
        .Attributes()
        .ToDictionary(attr => attr.Name, attr => attr.Value);
1 голос
/ 26 июля 2011

Используйте следующую XPath: //Dataset/@*, например:

var doc = XDocument.Load("a.txt");

var sMainTagName = "Cars";

string xPath = "Data/" + sMainTagName + "/Details/Dataset/@*";

var attr = (doc.Document.XPathEvaluate(xPath) as IEnumerable).Cast<XAttribute>();

foreach (var item in attr)
{
    Console.WriteLine("{0}: {1}", item.Name, item.Value);
}
...