none
Выбор уникальных значений при парсинге XML RRS feed

  • Вопрос

  • Доброго времени суток есть вопрос на каторый внятно не смог найти решение 

    Задача: есть XML

    <top>
        <name>
            <type>Dima</type>
            <date>12.12.2012</date>
       </name>
        <name>
            <type>Dima</type>
            <date>10.12.2012</date>
       </name>
        <name>
            <type>Vasy</type>
            <date>12.10.2012</date>
       </name>
        <name>
            <type>Vova</type>
            <date>12.09.2012</date>
       </name>
    </top>
    


    в нем есть значения которые дублируются их надо отсечь , что бы получилось на выходе 

    Dima 12.12.2012

    Vasy 12.10.2012

    Vova 12.09.2012

    7 октября 2011 г. 12:08

Ответы

  • примерно так

    public IEnumerable<string> Distinct(XElement xe)
    {
        var dt = new Dictionary<string, XNode>(StringComparer.OrdinalIgnoreCase);
        foreach(var xn in xe.Descendants("name"))
        {
            var xt = xn.Element("type");
            if(dt.ContainsKey(xt.Value) == false)
            {
                dt.Add(xt.Value, xn);
                yield return String.Concat(xt.Value, " ", xn.Element("date").Value);
            }
        }
    }
    ...
    
    var xe = XElement.Parse(@"
        <top>
            <name>
                <type>Dima</type>
                <date>12.12.2012</date>
            </name>
            <name>
                <type>Dima</type>
                <date>10.12.2012</date>
            </name>
            <name>
                <type>Vasy</type>
                <date>12.10.2012</date>
            </name>
            <name>
                <type>Vova</type>
                <date>12.09.2012</date>
            </name>
        </top>");
    foreach(var itm in Distinct(xe))
        System.Diagnostics.Trace.WriteLine(itm);
    

    • Помечено в качестве ответа DrakonoffNet 7 октября 2011 г. 12:56
    7 октября 2011 г. 12:33
  • другой вариант
    using System.Xml.XPath;
    ...
    var res = xe.XPathSelectElements("//name[not(type/text() = preceding-sibling::name/type/text())]");
    foreach (var itm in res.Select(xn => new {Type=xn.Element("type").Value, Date=xn.Element("date").Value}))
        System.Diagnostics.Trace.WriteLine(itm.Type + " " + itm.Date);
    
     
    • Помечено в качестве ответа DrakonoffNet 7 октября 2011 г. 12:56
    7 октября 2011 г. 12:44
  • еще один вариант

     

    var res =
            from x in xe.Descendants("name")
            group x by x.Element("type").Value into grp
            let f = grp.First()
            select new { Type = f.Element("type").Value, Date = f.Element("date").Value };
    foreach (var itm in res)
        System.Diagnostics.Trace.WriteLine(itm.Type + " " + itm.Date);
    

     


    • Изменено Malobukv 7 октября 2011 г. 12:59
    • Помечено в качестве ответа DrakonoffNet 7 октября 2011 г. 13:05
    7 октября 2011 г. 12:59

Все ответы

  • Используй Linq 2 XML и distinct.
     
    7 октября 2011 г. 12:18
    Модератор
  • примерно так

    public IEnumerable<string> Distinct(XElement xe)
    {
        var dt = new Dictionary<string, XNode>(StringComparer.OrdinalIgnoreCase);
        foreach(var xn in xe.Descendants("name"))
        {
            var xt = xn.Element("type");
            if(dt.ContainsKey(xt.Value) == false)
            {
                dt.Add(xt.Value, xn);
                yield return String.Concat(xt.Value, " ", xn.Element("date").Value);
            }
        }
    }
    ...
    
    var xe = XElement.Parse(@"
        <top>
            <name>
                <type>Dima</type>
                <date>12.12.2012</date>
            </name>
            <name>
                <type>Dima</type>
                <date>10.12.2012</date>
            </name>
            <name>
                <type>Vasy</type>
                <date>12.10.2012</date>
            </name>
            <name>
                <type>Vova</type>
                <date>12.09.2012</date>
            </name>
        </top>");
    foreach(var itm in Distinct(xe))
        System.Diagnostics.Trace.WriteLine(itm);
    

    • Помечено в качестве ответа DrakonoffNet 7 октября 2011 г. 12:56
    7 октября 2011 г. 12:33
  • другой вариант
    using System.Xml.XPath;
    ...
    var res = xe.XPathSelectElements("//name[not(type/text() = preceding-sibling::name/type/text())]");
    foreach (var itm in res.Select(xn => new {Type=xn.Element("type").Value, Date=xn.Element("date").Value}))
        System.Diagnostics.Trace.WriteLine(itm.Type + " " + itm.Date);
    
     
    • Помечено в качестве ответа DrakonoffNet 7 октября 2011 г. 12:56
    7 октября 2011 г. 12:44
  • другой вариант
    using System.Xml.XPath;
    ...
    var res = xe.XPathSelectElements("//name[not(type/text() = preceding-sibling::name/type/text())]");
    foreach (var itm in res.Select(xn => new {Type=xn.Element("type").Value, Date=xn.Element("date").Value}))
        System.Diagnostics.Trace.WriteLine(itm.Type + " " + itm.Date);
    
     

    Этот вариант короче и компактнее.

    Спасибо

    7 октября 2011 г. 12:57
  • еще один вариант

     

    var res =
            from x in xe.Descendants("name")
            group x by x.Element("type").Value into grp
            let f = grp.First()
            select new { Type = f.Element("type").Value, Date = f.Element("date").Value };
    foreach (var itm in res)
        System.Diagnostics.Trace.WriteLine(itm.Type + " " + itm.Date);
    

     


    • Изменено Malobukv 7 октября 2011 г. 12:59
    • Помечено в качестве ответа DrakonoffNet 7 октября 2011 г. 13:05
    7 октября 2011 г. 12:59