开发者

The best way to retrieve the attributes from xml elements using C#/.net 3.5

开发者 https://www.devze.com 2023-03-23 05:50 出处:网络
If we have a XML like: <Data> <Cars> <Details> <Dataset se-datafilter=\"cars\" dv-datamanipulationrequired=\"false\" dv-filtercondition=\"\" dv-sortcolumn=\"\" dv-gettopNrows=\"\

If we have a XML like:

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

What is the best way to retrieve the values of all the attributes stored in <Dataset> element for sMainTagName. sMainTagName can either have value "Cars" or "Jeeps". Passed from the UI.

I have the following code now:

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

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

foreach (var att in cols.Elemen开发者_C百科ts("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;
    }
}


I'm a fan of Linq to Xml. Here's an example:

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


How about returning a dictionary, build up from the attributes.

return xdoc.XPathSelectElements("/Data/" + sMainTagName + "/Details/Dataset")
        .Attributes()
        .ToDictionary(attr => attr.Name, attr => attr.Value);


Personally I wouldn't use XPath to start with. I'd do something like this:

// 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")) ?? "";

(I'm assuming there's only one Dataset element, by the way.);

This uses the fact that the explicit string conversion from XAttribute will return null if the attribute doesn't exist (i.e. you're calling it on a null reference).


Use following XPath: //Dataset/@*, e.g.:

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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号