Есть xml, полученный из Excel. Разметка выглядит примерно так, только строк значительно больше и блок Data
c "Number"
только один:
XML:
<Row>
<Cell>
<Data ss:Type="String">AAPL US Equity</Data>
</Cell>
<Cell>
<Data ss:Type="Number">150.25</Data>
</Cell>
<Cell>
<Data ss:Type="Number">1</Data>
</Cell>
</Row>
<Row>
<Cell>
<Data ss:Type="String">GOOGL Equity</Data>
</Cell>
<Cell>
<Data ss:Type="Number">942.17</Data>
</Cell>
<Cell>
<Data ss:Type="Number">2</Data>
</Cell>
</Row>
<Row>...</Row>
<Row>...</Row>
Использую XmlTextReader
, чтобы выбрать все значения из блока <Data ss:Type="String">
ВОТ ЭТО</Data >
(AAPL US Equity
и GOOGL Equity):
public void Go()
{
XmlTextReader ValueReader = new XmlTextReader("///book1.xml");
try
{
while (ValueReader.Read())
{
switch (ValueReader.NodeType)
{
case XmlNodeType.Element:
if (ValueReader.Name == "Cell")
{
ValueReader.MoveToElement();
var X = ValueReader.ReadOuterXml();
XmlDocument usdXmlDocument = new XmlDocument();
usdXmlDocument.LoadXml(X);
XmlNode xmlNode = usdXmlDocument.SelectSingleNode(@"Data ss:Type=""String""/Data");
MessageBox.Show(xmlNode.InnerText.ToString(), "");
}
break;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, ex.Source);
}
}
Исключение
Data ss:Type="String"/Number имеет недопустимый указатель(токен).
Буду благодарен за любую подсказку.
В метод SelectSingleNode
нужно передавать xpath-выражение. Вот это - @"Data ss:Type=""String""/Data"
- что-то странное, но никак не xpath.
Если использовать именно ваш алгоритм извлечения данных, с применением XmlDocument
, то минимальные изменения, которые нужно внести в код, это взять правильный xpath и добавить менеджер пространств имён. Пространства имён обязательно нужно учитывать, без этого никак.
var manager = new XmlNamespaceManager(usdXmlDocument.NameTable);
manager.AddNamespace("ss", "some-namespace");
XmlNode xmlNode = usdXmlDocument.SelectSingleNode(@"/Cell/Data[@ss:Type='String']", manager);
if (xmlNode != null)
MessageBox.Show(xmlNode.InnerText.ToString(), "");
Вместо some-namespace
укажите именно то, что у вас в XML. Где его взять? Ищите в своём xml объявление наподобие xmlns:ss="some-namespace"
. Вероятнее всего, оно будет в самом начале, в корневом элементе документа.
Код можно существенно упростить и ускорить его работу.
Класс XmlTextReader
считается устаревшим. Вместо него следует создавать экземпляры XmlReader
с помощью статического метода Create
.
После использования все Disposable
объекты следует освобождать. Проще всего это делать с применением конструкции using
.
Класс XmlReader
имеет много полезных методов. В нашем случае - однородная структура xml - удобно применить ReadToFollowing
. А для чтения атрибута - GetAttribute
. Пространство имён при этом обязательно нужно указывать! Естественно, заменить some-namespace
на настоящий.
Найдя элемент с нужным атрибутом, читаем его значение ReadElementContentAsString
.
using (var reader = XmlReader.Create("test.xml"))
{
while (reader.ReadToFollowing("Data"))
{
if (reader.GetAttribute("Type", "some-namespace") == "String")
MessageBox.Show(reader.ReadElementContentAsString());
}
}
Это весь код!
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Виртуальный выделенный сервер (VDS) становится отличным выбором
Стоит задача сделать приложение для отзывовРаботать оно будет на планшете, доступном клиентам
Как программно передать в параметр отчета несколько значений? Я передаю так :
Нужно написать сервер наNet-Core, Игра в целом пошаговая один на один, но во время хода противника можно слать эмоции как в Heartstone, так что последовательно...