2014-10-16 7 views
0

Это может быть самый простой вопрос для этого. Это часть моего xml. То, что я хочу получить, - это атрибут «Значение», основанный на другом атрибуте «ItemOID». IE, когда ItemOID = "I_MEDIC_HISTORY_INDICATION", каково значение.Получить другой атрибут в том же элементе, выполнив поиск другого атрибута

<FormData FormOID="F_NEUROLOGICAL_V20" OpenClinica:Version="V2.0" OpenClinica:Status="initial data entry"> 
    <ItemGroupData ItemGroupOID="IG_NEURO_UNGROUPED" ItemGroupRepeatKey="1" TransactionType="Insert"> 
     <ItemData ItemOID="I_NEURO_NEURO_TENDONAB" Value="" /> 
     <ItemData ItemOID="I_NEURO_NEURO_TENDON" Value="1" /> 
     <ItemData ItemOID="I_NEURO_NEURO_GAITAB" Value="" /> 
     <ItemData ItemOID="I_NEURO_NEURO_GAIT" Value="1" /> 
     <ItemData ItemOID="I_NEURO_NEURO_COORDINATEAB" Value="" /> 
     <ItemData ItemOID="I_NEURO_NEURO_COORDINATE" Value="1" /> 
     <ItemData ItemOID="I_NEURO_NEURO_SENSORYAB" Value="" /> 
     <ItemData ItemOID="I_NEURO_NEURO_SENSORY" Value="1" /> 
     <ItemData ItemOID="I_NEURO_NEURO_MUSCLETONEAB" Value="" /> 
     <ItemData ItemOID="I_NEURO_NEURO_MUSCLETONE" Value="1" /> 
     <ItemData ItemOID="I_NEURO_NEURO_MOTORAB" Value="" /> 
     <ItemData ItemOID="I_NEURO_NEURO_MOTOR" Value="1" /> 
     <ItemData ItemOID="I_NEURO_NEURO_CRANIALAB" Value="" /> 
     <ItemData ItemOID="I_NEURO_NEURO_CRANIAL" Value="1" /> 
     <ItemData ItemOID="I_NEURO_NEURO_SPEECHAB" Value="" /> 
     <ItemData ItemOID="I_NEURO_NEURO_SPEECH" Value="1" /> 
     <ItemData ItemOID="I_NEURO_NEURO_BEHAVEAB" Value="abnormal" /> 
     <ItemData ItemOID="I_NEURO_NEURO_BEHAVE" Value="0" /> 
     <ItemData ItemOID="I_NEURO_NEURO_APPEARAB" Value="" /> 
     <ItemData ItemOID="I_NEURO_NEURO_APPEAR" Value="1" /> 
     <ItemData ItemOID="I_NEURO_NEURO_NORMAL" Value="1" /> 
     <ItemData ItemOID="I_NEURO_NEURO_DATE" Value="2014-10-10" /> 
    </ItemGroupData> 
</FormData> 

Это мой код. Как вы можете сказать, я немного застрял.

string neuroExamPath = "//oc:FormData[@FormOID='F_NEUROLOGICAL_V20']/oc:ItemGroupData/oc:ItemData"; 
var neuroExamList = doc.XPathSelectElements(neuroExamPath, nsmgr).Reverse(); 

foreach (var neuroExamElement in neuroExamList) 
{ 
    var patrow = patDt.NewRow(); 
    var I_NEURO_NEURO_NORMAL = neuroExamElement.Attribute("Value").Value; 
    patrow["Neuro_normal"] = I_NEURO_NEURO_NORMAL; 
    var I_NEURO_NEURO_APPEAR = neuroExamElement.Attribute("Value").Value; 
    patrow["Neuro_appear"] = I_NEURO_NEURO_APPEAR; 
    var I_NEURO_NEURO_APPEARAB = neuroExamElement.Attribute("Value").Value; 
    patrow["Neuro_appearab"] = I_NEURO_NEURO_APPEARAB; 

    patDt.Rows.Add(patrow); 
} 

Как вы можете сказать, он будет перебирать все атрибуты Value все время. Однако мне нужен var I_NEURO_NEURO_NORMAL = neuroExamElement.Attribute («Значение»). Значение; чтобы иметь условие, в котором ItemOID = «I_NEURO_NEURO_NORMAL» и т. д. Поэтому я могу поместить один атрибут за раз в datatable. Пожалуйста помоги. Спасибо.

+0

Приложите больше усилий для форматирования кода в будущих вопросах. Сравните, как вы разместили его с текущей версией, и в следующий раз используйте предварительный просмотр, чтобы убедиться, что он имеет отступ, соответствующий перед отправкой. Чем проще вы делаете это для людей, чтобы читать и понимать ваш вопрос, тем больше/лучших ответов вы, вероятно, получите. –

+0

Жаль Джон. Новичок в публикации. Приветствия. – user3276223

ответ

1

Мне кажется, что вы хотите новый ряд для каждого элемента ItemGroupData, а не каждый элемент ItemData. Я бы ожидать что-то вроде:

foreach (var itemGroup in doc.Root.Elements("ItemGroupData")) 
{ 
    var row = patDt.NewRow(); 
    row["Neuro_normal"] = itemGroup.ExtractValue("I_NEURO_NEURO_NORMAL"); 
    row["Neuro_appear"] = itemGroup.ExtractValue("I_NEURO_NEURO_APPEAR"); 
    row["Neuro_appearab"] = itemGroup.ExtractValue("I_NEURO_NEURO_APPEARAB"); 
    patDt.Rows.Add(row); 
} 

, который использует новый метод расширения:

public static string ExtractValue(this XElement parent, string oid) 
{ 
    return parent.Elements("ItemData") 
       .Where(x => x.Attribute("ItemOID").Value == oid) 
       .First() 
       .Attribute("Value") 
       .Value; 
} 

В качестве альтернативы, если вы извлекая много атрибутов, можно создать словарь:

var values = itemGroup.Elements("ItemData") 
         .ToDictionary(x => x.Attribute("ItemOID").Value, 
            x => x.Attribute("Value").Value); 
+0

Это очень элегантное и удивительное решение. Нужно ли вообще добавить этот запрос в Xpath // oc: FormData [@ FormOID = 'F_NEUROLOGICAL_V20']? Я хочу уменьшить его на основе FormData. Это огромный xml со многими деревьями user3276223

+0

@ user3276223: Я бы не использовал XPath для этого - я бы использовал 'doc.Descendants (ns +" FormData "). Где (x => x.Attribute (" FormOID "). Значение ==" F_NEUROLOGICAL_V20 ") 'где' ns' является подходящим пространством имен (это то, что я предполагаю 'oc' is). Вы, конечно, можете * использовать XPath вместо этого, но я предпочитаю не встраивать один язык в другой, если я могу ему помочь. –