Есть 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());
}
}
Это весь код!
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости