Чтение смежных элементов в XML
У меня есть большой файл XML, и поэтому я использую XMLTextReader. У меня проблемы с чтением значения, потому что форматирование немного отличается от других файлов XML, с которыми я работал.
<class>
<column>Size</column><int>30</int>
<column>TeamColor</column><string>red</string>
...
</class>
Как я могу прочитать Размер, а затем получить значение 30? У меня сейчас есть
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
element = reader.Name;
else if (reader.NodeType == XmlNodeType.Text)
{
if (element == "column")
{
if(reader.Value == "Size")
//can get true here, but can't return the int value next to it
}
}
}
3 ответа
Вы можете получить все столбцы с их именем и соответствующим значением в Hashtable
,
Попробуйте использовать этот фрагмент кода:
Hashtable hashTable = new Hashtable();
int intVal;
string prevColumnName = "";
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
element = reader.Name;
}
else if (reader.NodeType == XmlNodeType.Text)
{
switch (element.ToLower())
{
case "column":
prevColumnName = reader.Value;
hashTable.Add(reader.Value, null);
break;
case "int":
if (int.TryParse(reader.Value, out intVal))
hashTable[prevColumnName] = intVal;
break;
case "string":
hashTable[prevColumnName] = reader.Value;
break;
}
}
}
Использование:
int size = Convert.ToInt32(hashTable["Size"]);
Если вы можете использовать xpath, из <column>
попытка контекстного узла (following-sibling::*)[1]
, Это выберет элементы *
вдоль оси "следующий брат" (вещи, которые сопоставляются с контекстом, но следуют в порядке документов), а затем возвращают первый элемент последовательности.
Если вы не сохраните предыдущее значение, вам нужно будет добавить условие пропуска, позволяющее вам выполнить дополнительное чтение (для родного брата), когда оно достигает элемента столбца, а затем правильно обработать все дополнительные чтения в следующем цикле.
bool skipRead = false;
while (skipRead || reader.Read())
{
skipRead = false;
if (reader.NodeType == XmlNodeType.Element)
element = reader.Name;
else if (reader.NodeType == XmlNodeType.Text)
{
if (element == "column")
{
if (Reader.Read())
{
if(reader.NodeType == XmlNodeType.Element && reader.Name == "Size")
{
// do whatever you need to here with reader.Value.
// E.g size = (int) reader.Value
skipRead = false;
continue;
} // Additional ifs for other elements in column can go here.
else
{
skipRead = true;
continue;
}
}
else
{
break;
}
}
}
}