2014-01-28 2 views
1

Я имею дело с XML-файлом, который имеет очень вложенную структуру:Получить общее значение элемента из сложного XML

<?xml version="1.0" encoding="utf-8"?> 
<Root> 
    <Stuff> 
     <Item Class="Consumable"> 
      <CalledAs>ResourceAlpha</CalledAs> 
      <ID>ResourceAlpha25367</ID> 
     </Item> 
     <Item Class="Consumable"> 
      <CalledAs>ResourceAlpha</CalledAs> 
      <ID>ResourceAlpha25368</ID> 
     </Item> 
     <Item Class="Consumable"> 
      <CalledAs>ResourceAlpha</CalledAs> 
      <ID>ResourceAlpha25371</ID> 
     </Item> 
     <Item Class="Consumable"> 
      <CalledAs>ResourceAlpha</CalledAs> 
      <ID>ResourceAlpha25372</ID> 
     </Item> 
     <Item Class="Consumable"> 
      <CalledAs>ResourceBeta</CalledAs> 
      <ID>ResourceBeta25376</ID> 
     </Item> 
     <Item Class="Consumable"> 
      <CalledAs>ResourceBeta</CalledAs> 
      <ID>ResourceBeta25377</ID> 
     </Item> 
     <Item Class="Consumable"> 
      <CalledAs>ResourceBeta</CalledAs> 
      <ID>ResourceBeta25381</ID> 
     </Item> 
     <Item Class="Consumable"> 
      <CalledAs>ResourceBeta</CalledAs> 
      <ID>ResourceBeta25384</ID> 
     </Item> 
     <Item Class="Consumable"> 
      <CalledAs>ResourceBeta</CalledAs> 
      <ID>ResourceBeta25388</ID> 
     </Item> 

     <Item Class="Construct"> 
      <Named>ClosedFolders</Named> 
      <ID>ClosedFolders25393</ID> 
      <StorageCabinet>(102, 0, 94)</StorageCabinet> 
      <AssignedTo>Colonist</AssignedTo> 
      <Assigned Class="Consumable"> 
       <CalledAs>ResourceBeta</CalledAs> 
       <ID>ResourceBeta25238</ID> 
      </Assigned> 
     </Item> 
     <Item Class="Construct"> 
      <Named>ClosedFolders</Named> 
      <ID>ClosedFolders25394</ID> 
      <StorageCabinet>(105, 0, 95)</StorageCabinet> 
      <AssignedTo>Colonist</AssignedTo> 
     </Item> 
     <Item Class="Construct"> 
      <Named>ClosedFolders</Named> 
      <ID>ClosedFolders25395</ID> 
      <StorageCabinet>(103, 0, 92)</StorageCabinet> 
      <AssignedTo>Colonist</AssignedTo> 
      <Assigned Class="Consumable"> 
       <CalledAs>ResourceAlpha</CalledAs> 
       <ID>ResourceBeta45232</ID> 
      </Assigned>   
     </Item> 

    </Stuff> 
</Root> 

Теперь мне нужно получить список всех ID, так что, когда я добавляю новый Consumable или Assigned, я могу сгенерировать (и убедиться, что это уникальный) новый идентификатор.

Вот как я загружаю файл:

String savefile = Settings.Default.SelectedSaveFilePath; 

    var xmlDocument = new XmlDocument(); 
    xmlDocument.Load(savefile); 

    var selectSingleNode = xmlDocument.SelectSingleNode("/Root/Stuff/Item[@Class='Consumable']"); 
    if (selectSingleNode != null) 
    { 
     // Attempt to loop 
    } 

Теперь на уровне /Root/Stuff/Item[@Class='Consumable'], я хорошо для получения <ID> но есть вложенности в /Root/Stuff/Item[@Class='Construct'], которые требуют своего рода суб- для каждого, чтобы получить <ID> от <Assigned Class="Consumable">

Я пытаюсь создать список всех <ID> узлов во всем документе, а если возможно, коллекции Key-Value где <ID> является Валу e и Element (из них <ID> принадлежит) в качестве ключа.

Я также знаю, что <ID> являются уникальными в документе независимо от их родителя. Поэтому я могу найти любой элемент, выполнив поиск только идентификатора.

Я надеюсь, что это имеет смысл.

Спасибо.

+0

Список всех значений элемента ID? Хорошо, это звучит достаточно просто - но вы узнаете больше, если попытаетесь найти ответ для себя. Что вы уже пробовали, и что пошло не так? –

+0

Не могу сделать путь. Данный пример очень прост. Фактические данные составляют более 25 МБ XML и чувствительны, поэтому я не вставляю. – DoomerDGR8

+0

Что вы подразумеваете под «make the path»? Можете ли вы хотя бы загрузить документ в LINQ to XML? Я не запрашивал фактические данные ... –

ответ

2

Итак, вам нужно получить все идентификаторы, и если вы хотите добавить новый элемент, вам нужно проверить, существует ли предмет с данным идентификатором?

var idList = XDocument.Load("path") 
         .Descendants("ID") 
         .Select(x => (string)x); 

if(idList.Contains(givenId)) 
{ 
    ... 
} 

Или используйте HashSet для быстрого поиска:

var hashSet = new HashSet<string>(idList); 
if(hashSet.Contains(givenId)) 
{ 
    ... 
} 
+0

И если я загружаю XML как: 'вар XMLDOCUMENT = новый XmlDocument();' ' xmlDocument.Load (SAVEFILE);' Т.е. , не используя 'XDocument'? – DoomerDGR8

+0

вы можете это сделать, но «LINQ to XML» лучше и удобнее использовать –

1

Вы можете использовать HashSet для быстрого поиска

var ids = new HashSet<string>( 
       XDocument.Load(filename) 
        .Descendants("ID") 
        .Select(x => (string)x)); 

или (с помощью класса XmlDocument, как в вашем редактирования).

XmlDocument xmlDocument = new XmlDocument(); 
xmlDocument.Load(filename); 
var ids = new HashSet<string>(
       xmlDocument.GetElementsByTagName("ID") 
        .Cast<XmlNode>() 
        .Select(x => x.InnerText)); 
Смежные вопросы