отдельные значения в XML - PullRequest
1 голос
/ 10 марта 2019

пожалуйста, кто-то может помочь с отчетливым в xpath?Я пытаюсь сделать какой-нибудь запрос, который возвращает количество разных актеров, которые родились после года, и которые имеют сумму, превышающую сумму вознаграждения в одном фильме или одном телешоу.

, поэтому сначала я выбираю всех актеровчто их год рождения выше параметра года, и чем я использую счет для подсчета их наград.но теперь у меня есть дубликаты имен, как я могу отличить мой результат?

мой код:

public int Query6(XmlDocument xmlDoc, String yearOfBirth, int amountOfAwards)
        {
            string s = "//actors/actor[year-of-birth>'" + yearOfBirth + "'][count(awards/award)>"+amountOfAwards+"]";

            XmlNodeList xmlNodeList = xmlDoc.SelectNodes(s);
            return xmlNodeList.Count;
        }

XMLDoc:

<?xml version="1.0"?>
<Netflix>
  <movies>
    <movie>
      <name>Mister Glass</name>
      <genre>Drama</genre>
      <year>2019</year>
      <actors>
        <actor>
          <first-name>James</first-name>
          <last-name>McAvoy</last-name>
          <year-of-birth>1979 </year-of-birth>
          <awards>
            <award>
              <category>Alliance of Women Film Journalists</category>
              <year>2007</year>
            </award>
            <award>
              <category>ALOS Awards</category>
              <year>2018</year>
            </award>
          </awards>
        </actor>
        <actor>
          <first-name>Bruce</first-name>
          <last-name>Willis</last-name>
          <year-of-birth>1955 </year-of-birth>
          <awards>
            <award>
              <category>American gun rights advocates</category>
              <year>2007</year>
            </award>
            <award>
              <category>American film producers</category>
              <year>2013</year>
            </award>
            <award>
              <category>American male video game actors</category>
              <year>2012</year>
            </award>
            <award>
              <category>American male television actors</category>
              <year>2013</year>
            </award>
          </awards>
        </actor>
      </actors>
    </movie>
    <movie>
      <name>Aquaman</name>
      <genre>Action</genre>
      <year>2018</year>
      <actors>
        <actor>
          <first-name>Jason</first-name>
          <last-name>Momoa</last-name>
          <year-of-birth>1979</year-of-birth>
          <awards>
            <award>
              <category>Rising Star</category>
              <year>2011</year>
            </award>
          </awards>
        </actor>
        <actor>
          <first-name>Amber</first-name>
          <last-name>Heard</last-name>
          <year-of-birth>1986</year-of-birth>
          <awards>
            <award>
              <category>Dallas Star Award</category>
              <year>2010</year>
            </award>
            <award>
              <category>Spotlight Award</category>
              <year>2011</year>
            </award>
          </awards>
        </actor>
      </actors>
    </movie>
    <movie>
      <name>Split</name>
      <genre>Horror</genre>
      <year>2016</year>
      <actors>
        <actor>
          <first-name>James</first-name>
          <last-name>McAvoy</last-name>
          <year-of-birth>1979 </year-of-birth>
          <awards>
            <award>
              <category>Best Actor - Audience Award</category>
              <year>2017</year>
            </award>
          </awards>
        </actor>
      </actors>
    </movie>
    <movie>
      <name>harry potter</name>
      <genere>fantasy</genere>
      <year>1997</year>
      <actors>
        <actor>
          <first-name>Daniel</first-name>
          <last-name>Radcliffe</last-name>
          <year-of-birth>1989</year-of-birth>
          <awards>
            <award>
              <category>Male Youth Discovery of the Year</category>
              <year>2001</year>
            </award>
            <award>
              <category>Choice Movie: Male Breakout Star</category>
              <year>2001</year>
            </award>
            <award>
              <category>Best Actor</category>
              <year>2008</year>
            </award>
          </awards>
        </actor>
        <actor>
          <first-name>emma</first-name>
          <last-name>watson</last-name>
          <year-of-birth>1990</year-of-birth>
        </actor>
        <actor>
          <first-name>Alba</first-name>
          <last-name>Florez</last-name>
          <year-of-birth>1986</year-of-birth>
          <awards>
            <award>
              <category>Best Female Performer in Fiction</category>
              <year>2000</year>
            </award>
          </awards>
        </actor>
      </actors>
    </movie>
    <movie>
      <name>Miss Bala </name>
      <genre>Action</genre>
      <year>2019</year>
      <actors>
        <actor>
          <first-name>Gina</first-name>
          <last-name>Rodriguez</last-name>
          <year-of-birth>1984</year-of-birth>
        </actor>
        <actor>
          <first-name>Thomas</first-name>
          <last-name>Dekker</last-name>
          <year-of-birth>1987</year-of-birth>
        </actor>
      </actors>
    </movie>
    <movie>
      <name>The Dark Knight</name>
      <genre>Action</genre>
      <year>2008</year>
      <actors>
        <actor>
          <first-name>Christian</first-name>
          <last-name>Bale</last-name>
          <year-of-birth>1974</year-of-birth>
          <awards>
            <award>
              <category>Best Actor</category>
              <year>2013</year>
            </award>
            <award>
              <category>Best Cast Ensemble</category>
              <year>2008</year>
            </award>
          </awards>
        </actor>
      </actors>
    </movie>
    <movie>
      <name>Forrest Gump</name>
      <genre>Drama</genre>
      <year>1994</year>
      <actors>
        <actor>
          <first-name>Tom</first-name>
          <last-name>Hanks</last-name>
          <year-of-birth>1956</year-of-birth>
          <awards>
            <award>
              <category>Best Actor in a Leading Role</category>
              <year>1994</year>
            </award>
            <award>
              <category>Best Performance by an Actor in a Motion Picture - Drama</category>
              <year>1995</year>
            </award>
          </awards>
        </actor>
        <actor>
          <first-name>Robin</first-name>
          <last-name>Wright</last-name>
          <year-of-birth>1966</year-of-birth>
          <awards>
            <award>
              <category>Best Performance by an Actress in a Supporting Role in a Motion Picture</category>
              <year>1994</year>
            </award>
          </awards>
        </actor>
      </actors>
    </movie>
    <movie>
      <name>Star Wars</name>
      <genre>Action</genre>
      <year>1977</year>
      <actors>
        <actor>
          <first-name>Harrison</first-name>
          <last-name>Ford</last-name>
          <year-of-birth>1942</year-of-birth>
          <awards>
            <award>
              <category>Best Actor</category>
              <year>1997</year>
            </award>
          </awards>
        </actor>
        <actor>
          <first-name>Mark</first-name>
          <last-name>Hamill</last-name>
          <year-of-birth>1951</year-of-birth>
        </actor>
      </actors>
    </movie>
    <movie>
      <name>Gladiator</name>
      <genre>Action</genre>
      <year>2000</year>
      <actors>
        <actor>
          <first-name>Russell</first-name>
          <last-name>Crowe</last-name>
          <year-of-birth>1964</year-of-birth>
          <awards>
            <award>
              <category>Best Actor in a Leading Role</category>
              <year>2000</year>
            </award>
            <award>
              <category>Best Performance by an Actor in a Motion Picture - Drama</category>
              <year>2000</year>
            </award>
          </awards>
        </actor>
        <actor>
          <first-name>Joaquin</first-name>
          <last-name>Phoenix</last-name>
          <year-of-birth>1974</year-of-birth>
          <awards>
            <award>
              <category>Best Actor in a Supporting Role</category>
              <year>2000</year>
            </award>
            <award>
              <category>Best Performance by an Actor in a Supporting Role in a Motion Picture</category>
              <year>2000</year>
            </award>
          </awards>
        </actor>
      </actors>
    </movie>
    <movie>
      <name>Ted</name>
      <genre>Comedy</genre>
      <year>2015</year>
      <actors>
        <actor>
          <first-name>Mila</first-name>
          <last-name>Kunis</last-name>
          <year-of-birth>1983</year-of-birth>
          <awards>
            <award>
              <category>Young Artist Awards</category>
              <year>2001</year>
            </award>
            <award>
              <category>Teen Choice Awards</category>
              <year>2010</year>
            </award>
          </awards>
        </actor>
      </actors>
    </movie>
  </movies>
  <TV-shows>
    <TV-show>
      <name>Narcos</name>
      <genre>Crime</genre>
      <year>2015</year>
      <seasons>
        <season>
          <episodes>10</episodes>
        </season>
        <season>
          <episodes>10</episodes>
        </season>
        <season>
          <episodes>10</episodes>
        </season>
      </seasons>
      <actors>
        <actor>
          <first-name>Wagner</first-name>
          <last-name>Maniçoba de Moura</last-name>
          <year-of-birth>1976</year-of-birth>
        </actor>
        <actor>
          <first-name>Pedro</first-name>
          <last-name>Pascal</last-name>
          <year-of-birth>1975</year-of-birth>
        </actor>
        <actor>
          <first-name>James</first-name>
          <last-name>Clarke</last-name>
          <year-of-birth>1986</year-of-birth>
          <awards>
            <award>
              <category>Outstanding Female Rising Star in a Drama Series or Special</category>
              <year>2012</year>
            </award>
          </awards>
        </actor>
        <actor>
          <first-name>Daniel</first-name>
          <last-name>Radcliffe</last-name>
          <year-of-birth>1989</year-of-birth>
          <awards>
            <award>
              <category>Male Youth Discovery of the Year</category>
              <year>2001</year>
            </award>
            <award>
              <category>Choice Movie: Male Breakout Star</category>
              <year>2001</year>
            </award>
            <award>
              <category>Best Actor</category>
              <year>2008</year>
            </award>
          </awards>
        </actor>
      </actors>
    </TV-show>
    <TV-show>
      <name>Game of Thrones</name>
      <genre>Action</genre>
      <year>2011</year>
      <seasons>
        <season>
          <episodes>10</episodes>
        </season>
        <season>
          <episodes>10</episodes>
        </season>
        <season>
          <episodes>10</episodes>
        </season>
        <season>
          <episodes>10</episodes>
        </season>
        <season>
          <episodes>10</episodes>
        </season>
        <season>
          <episodes>10</episodes>
        </season>
        <season>
          <episodes>7</episodes>
        </season>
      </seasons>
      <actors>
        <actor>
          <first-name>Emilia</first-name>
          <last-name>Clarke</last-name>
          <year-of-birth>1986</year-of-birth>
          <awards>
            <award>
              <category>Outstanding Female Rising Star in a Drama Series or Special</category>
              <year>2012</year>
            </award>
            <award>
              <category>Best Supporting Actress in a Drama Series</category>
              <year>2013</year>
            </award>
            <award>
              <category>Breakout Performance - Female</category>
              <year>2011</year>
            </award>
          </awards>
        </actor>
        <actor>
          <first-name>Peter</first-name>
          <last-name>Dinklage</last-name>
          <year-of-birth>1969</year-of-birth>
          <awards>
            <award>
              <category>Outstanding Supporting Actor in a Drama Series</category>
              <year>2018</year>
            </award>
          </awards>
        </actor>
      </actors>
    </TV-show>
    <TV-show>
      <name>The Sopranos</name>
      <genre>Crime</genre>
      <year>1999</year>
      <seasons>
        <season>
          <episodes>13</episodes>
        </season>
        <season>
          <episodes>13</episodes>
        </season>
        <season>
          <episodes>13</episodes>
        </season>
        <season>
          <episodes>13</episodes>
        </season>
        <season>
          <episodes>13</episodes>
        </season>
        <season>
          <episodes>21</episodes>
        </season>
      </seasons>
      <actors>
        <actor>
          <first-name>James</first-name>
          <last-name>Gandolfini</last-name>
          <year-of-birth>1961</year-of-birth>
          <awards>
            <award>
              <category>Best Performance by an Actor in a Television Series - Drama</category>
              <year>2000</year>
            </award>
            <award>
              <category>Outstanding Lead Actor in a Drama Series</category>
              <year>2003</year>
            </award>
          </awards>
        </actor>
        <actor>
          <first-name>Lorraine</first-name>
          <last-name>Bracco</last-name>
          <year-of-birth>1954</year-of-birth>
          <awards>
            <award>
              <category>Outstanding Performance by an Ensemble in a Drama Series</category>
              <year>2008</year>
            </award>
          </awards>
        </actor>
      </actors>
    </TV-show>
    <TV-show>
      <name>Black Mirror</name>
      <genre>Drama</genre>
      <year>2011</year>
      <seasons>
        <season>
          <episodes>3</episodes>
        </season>
        <season>
          <episodes>3</episodes>
        </season>
        <season>
          <episodes>6</episodes>
        </season>
        <season>
          <episodes>6</episodes>
        </season>
      </seasons>
      <actors>
        <actor>
          <first-name>Daniel</first-name>
          <last-name>Lapaine</last-name>
          <year-of-birth>1971</year-of-birth>
        </actor>
      </actors>
    </TV-show>
    <TV-show>
      <name>Westworld</name>
      <genre>Drama</genre>
      <year>2016</year>
      <seasons>
        <season>
          <episodes>10</episodes>
        </season>
        <season>
          <episodes>10</episodes>
        </season>
      </seasons>
      <actors>
        <actor>
          <first-name>Jeffrey</first-name>
          <last-name>Wright</last-name>
          <year-of-birth>1965</year-of-birth>
          <awards>
            <award>
              <category>Best TV Actor</category>
              <year>2016</year>
            </award>
          </awards>
        </actor>
        <actor>
          <first-name>Ed</first-name>
          <last-name>Harris</last-name>
          <year-of-birth>1950</year-of-birth>
          <awards>
            <award>
              <category>Best Supporting Actor on Television</category>
              <year>2017</year>
            </award>
          </awards>
        </actor>
      </actors>
    </TV-show>
    <TV-show>
      <name>Big Little Lies</name>
      <genre>Crime</genre>
      <year>2017</year>
      <seasons>
        <season>
          <episodes>7</episodes>
        </season>
      </seasons>
      <actors>
        <actor>
          <first-name>Reese</first-name>
          <last-name>Witherspoon</last-name>
          <year-of-birth>1976</year-of-birth>
          <awards>
            <award>
              <category>Outstanding Limited Series</category>
              <year>2017</year>
            </award>
          </awards>
        </actor>
        <actor>
          <first-name>Nicole</first-name>
          <last-name>Kidman</last-name>
          <year-of-birth>1967</year-of-birth>
          <awards>
            <award>
              <category>Best Performance by an Actress in a Limited Series or a Motion Picture Made for Television</category>
              <year>2018</year>
            </award>
            <award>
              <category>Outstanding Lead Actress in a Limited Series or Movie</category>
              <year>2017</year>
            </award>
          </awards>
        </actor>
      </actors>
    </TV-show>
    <TV-show>
      <name>The Night Of</name>
      <genre>Crime</genre>
      <year>2016</year>
      <seasons>
        <season>
          <episodes>8</episodes>
        </season>
      </seasons>
      <actors>
        <actor>
          <first-name>Riz</first-name>
          <last-name>Ahmed</last-name>
          <year-of-birth>1982</year-of-birth>
          <awards>
            <award>
              <category>Outstanding Lead Actor in a Limited Series or Movie</category>
              <year>2017</year>
            </award>
          </awards>
        </actor>
        <actor>
          <first-name>John</first-name>
          <last-name>Turturro</last-name>
          <year-of-birth>1957</year-of-birth>
        </actor>
      </actors>
    </TV-show>
    <TV-show>
      <name>Mr. Bean</name>
      <genre>Comedy</genre>
      <year>1990</year>
      <seasons>
        <season>
          <episodes>15</episodes>
        </season>
      </seasons>
      <actors>
        <actor>
          <first-name>Rowan</first-name>
          <last-name>Atkinson</last-name>
          <year-of-birth>1955</year-of-birth>
        </actor>
      </actors>
    </TV-show>
    <TV-show>
      <name>The Handmaid's Tale</name>
      <genre>Drama</genre>
      <year>2017</year>
      <seasons>
        <season>
          <episodes>10</episodes>
        </season>
        <season>
          <episodes>13</episodes>
        </season>
      </seasons>
      <actors>
        <actor>
          <first-name>Elisabeth</first-name>
          <last-name>Moss </last-name>
          <year-of-birth>1982</year-of-birth>
          <awards>
            <award>
              <category>Best Performance by an Actress in a Television Series - Drama</category>
              <year>2018</year>
            </award>
            <award>
              <category>Outstanding Drama Series</category>
              <year>2017</year>
            </award>
          </awards>
        </actor>
        <actor>
          <first-name>Max</first-name>
          <last-name>Minghella</last-name>
          <year-of-birth>1985</year-of-birth>
        </actor>
      </actors>
    </TV-show>
    <TV-show>
      <name>Casa De Papel</name>
      <genre>Drama</genre>
      <year>2017</year>
      <seasons>
        <season>
          <episodes>13</episodes>
        </season>
        <season>
          <episodes>9</episodes>
        </season>
      </seasons>
      <actors>
        <actor>
          <first-name>Alba</first-name>
          <last-name>Florez</last-name>
          <year-of-birth>1986</year-of-birth>
          <awards>
            <award>
              <category>Best Supporting Actress in a Television Series </category>
              <year>2015</year>
            </award>
          </awards>
        </actor>
        <actor>
          <first-name>Álvaro</first-name>
          <last-name>Morte</last-name>
          <year-of-birth>1975</year-of-birth>
        </actor>
      </actors>
    </TV-show>
  </TV-shows>
</Netflix>

так, например, если я выберу год1980 и 3 награды, поэтому в моем результате «Дэниел Рэдклифф» будет засчитан дважды, и я хочу, чтобы он получил только 1.

Я пишу на c #.

Ответы [ 4 ]

1 голос
/ 10 марта 2019

Вы можете сделать следующее.

var result = xDocument.Descendants("actor")
     .Where(x=>x.Descendants("award").Any()) // You can skip this is if you want to consider Actors who haven't won any award
     .Select(x=>new 
     {
        Actor=$"{x.Element("first-name").Value} {x.Element("last-name").Value}",
        YearOfBirth = Int32.Parse(x.Element("year-of-birth").Value),
        AwardCount = x.Descendants("award").Count()
    })
    .GroupBy(x=>x.Actor)
    .Where(x=>x.First().YearOfBirth>Int32.Parse(yearOfBirth) && x.Sum(c=>c.AwardCount)>amountOfAwards)
    .Select(x=> new 
    {
        Actor = x.Key,
        YearOfBirth = x.First().YearOfBirth,
        Awards = x.Sum(c=>c.AwardCount)
    });

Выход (за 1980 год, сумма 3)

enter image description here

1 голос
/ 10 марта 2019

Это не может быть легко сделано в XPath 1.0, но это легко с XPath 2.0.Ядро Microsoft XPath в комплекте с .NET не поддерживает XPath 2.0, но есть альтернативы от третьих лиц (например, Saxon), которые делают.

Я не уверен, какой именно вывод вы хотите, но если вы это сделаетезапрос, который выбирает набор actor элементов (скажем, результат в $ selectedActors), затем вы можете получить различные имена этих акторов, используя

distinct-values($selectedActors/concat(first-name, ' ', last-name))

XPath имеетпройти долгий путь с 1.0.К сожалению, Microsoft никогда не внедряла более поздние версии: они предпочли бы, чтобы вы перешли на собственные проприетарные технологии (LINQ).Перейдете ли вы на LINQ или более поздние механизмы XPath от сторонних производителей, зависит от вашего отношения к блокировке Microsoft.

0 голосов
/ 10 марта 2019

Если вам действительно нужно решение XPath 1.0, вы можете использовать этот запрос, чтобы получить всех актеров с уникальной фамилией:

/Netflix/*/*/actors/actor[not(last-name = preceding::actor/last-name)

Конечно, это означает, что Джеффри Райт и Робин Райт не считаются уникальными актерами. Вы можете добавить больше критериев, как это:

/Netflix/*/*/actors/actor[not(last-name = preceding::actor/last-name) or not(first-name = preceding::actor/first-name) or not(year-of-birth = preceding::actor/year-of-birth)], и в этом случае запись будет считаться уникальной, если она имеет уникальную фамилию, уникальное имя или уникальный год рождения. Но это явно не водонепроницаемый! Это становится действительным решением, только если вы можете добавить уникальный идентификатор для каждого актера. Без этого я не думаю, что на самом деле это возможно сделать в чистом XPath 1.0.

0 голосов
/ 10 марта 2019

Я не думаю, что XQuery способен на то, что вы хотите, так как у вас есть несколько записей с одним и тем же актером.Это означает, что вам нужно агрегировать по элементам, чтобы получить общее количество наград за актера.

Вот решение, которое использует Linq для достижения того же результата:

public class Actor
{ 
    public string Name { get; set; }
    public int Awards { get; set; }
    public int BirthYear { get; set; }

    public override int GetHashCode() => 0;

    public override bool Equals(object obj) =>(obj as Actor)?.Name.Equals(this.Name) ?? base.Equals(obj);
}


public IEnumerable<Actor> GetActorsAndAwards(XDocument xml)
{
    foreach (var actor in xml.XPathSelectElements(@"//actors/actor"))
    {
        yield return new Actor
        {
            Name = $"{actor.Element("first-name").Value}, {actor.Element("last-name").Value}",
            Awards = actor.XPathSelectElements(@"awards/award").Count(),
            BirthYear = int.Parse(actor.Element("year-of-birth").Value)
        };
    };
}

public IEnumerable<Actor> AggregateAndFilter(IEnumerable<Actor> actors, int yearOfBirth, int amountOfAwards)
    => actors
        .GroupBy(x => x.Name)
        .Select(x => new Actor { Name = x.Key, BirthYear = x.First().BirthYear, Awards = x.Sum(y => y.Awards) })
        .Where(x => x.BirthYear > yearOfBirth && x.Awards > amountOfAwards)
        ;


void Main()
{
    var xml = XDocument.Load(@"D:\Temp\0\netflix.xml");

    AggregateAndFilter(GetActorsAndAwards(xml), 1970, 2).Count().Dump(); //Dump is LinqPad tool, do whatever you want with the result
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...