2016-09-28 3 views
0

У меня очень сложный XML, и мне нужно проверить, существует ли какой-то конкретный элемент только один раз внутри каждого дочернего элемента XML.Найти повторяющиеся элементы на основе другого значения тега XML

<?xml version="1.0" encoding="UTF-8"?> 
<deal> 
    <commercial> 
     <party /> 
     <party> 
     <role_detail> 
      <role_type>Primary</role_type> 
     </role_detail> 
     <listingagents> 
      <listingagent>1</listingagent> 
      <listingagent>2</listingagent> 
     </listingagents> 
     </party> 
     <party> 
     <role_detail> 
      <role_type>Secondary</role_type> 
     </role_detail> 
     <listingagents> 
      <listingagent>1</listingagent> 
     </listingagents> 
     </party> 
     <party /> 
    </commercial> 
    <commercial /> 
    <commercial /> 
</deal> 

Каждый коммерческий тег должен содержать только один тег listingagent, когда партия тега role_type = PRIMARY.

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

+2

серия xpaths может сделать трюк. вы что-то пробовали? – Ted

+0

Каковы требования, если у партии * нет * есть тип роли PRIMARY? И похоже, что это элемент listingAgent в теге * party *, а не в теге * commercial *. (Это также помогло бы, если бы вы отделили XML для удобства чтения.) –

+0

Он будет иметь тип первичной ролей. Да, элемент регистрации находится внутри Стороны. Но мне нужно выполнить эту проверку на весь xml для каждого коммерческого тега. Мне нужно сделать это с помощью LINQ –

ответ

0

Использование XML schema.xsd и ограничить ваше место:

Например:

<xs:element name="listingagents" maxOccurs="unbounded" type="listingagentsType"/> 

<xs:complexType name="listingagentsType"> 
    <xs:sequence> 
    <xs:element name="listingagent" type="parameterType" maxOccurs="1"/> 
    </xs:sequence> 

+0

Но это может произойти более одного раза во всем файле. Это должно происходить один раз для каждого основного типа роли –

+0

listingagent будет происходить 0 или 1 раз каждый раз, когда он будет вложен в листинг. Вы также можете установить minOccurs. – Rom

0
XElement xml = //... 
bool xmlIsInvalid = xml.Elements("commercial") 
    .Select(c => c.Elements("party") 
    .Single(p => p.Element("role_detail").Element("role_type").Value == "Primary")) 
    .Any(p => p.Element("listingagents").Elements("listingagent").Count() > 1); 

Для каждого commercial элемента, получить единственный ребенок party элемент которого role_type является Primary , Возвращает true, если какой-либо из этих элементов party содержит более 1 listingagent в listingagents.

Примечание это решение предполагает ряд вещей, о структуре вашего XML - т.е. party всегда есть элемент ребенок role_detail, listingagents всегда будет иметь по крайней мере один listingagent и т.д.

+0

будет ли это работать, если есть несколько коммерческих тегов? –

+0

Да, он обрабатывает каждый коммерческий тег и устанавливает значение «xmlIsInValid» в true, если какой-либо из них не соответствует критериям. – TVOHM

+0

Hey Не могу использовать .Single (p => p.Element "role_type"). Значение == "Первичный")) в 4-й строке ??? –

0

Мне нравится запрашивая XML узлов с XDocument (System.Xml.Linq). Сначала я найду недействительные первичные стороны с более чем 1 листинговым агентом и оттуда ...

XDocument doc = XDocument.Parse(File.ReadAllText("XMLFile1.xml")); 
var allParties = doc.Descendants("commercial").Elements("party"); 

// invalid primary parties with more than 1 listing agent 
var invalidPrimaries = allParties.Where(p => p.Element("role_detail")?.Value.ToUpper() == "PRIMARY" && 
              p.Element("listingagents")?.Elements("listingagent").Count() > 1); 

var validParties = allParties.Except(invalidPrimaries); 
var validCommericals = validParties.Select(p => p.Parent).Distinct().ToList(); 
+0

Привет, что если role_detail не является прямым ребенком партии? –

+0

Обратите внимание на использование символа '?.'null условный оператор, чтобы продолжать оценивать, если он не является нулевым (тег _party_ имеет дочерний элемент _role_detail_) https://msdn.microsoft.com/en-us/library/dn986595.aspx – Fredrik