Чтение определенных XML-элементов из файла XML
У меня есть следующий файл XML
<lexicon>
<word>
<base>a</base>
<category>determiner</category>
<id>E0006419</id>
</word>
<word>
<base>abandon</base>
<category>verb</category>
<id>E0006429</id>
<ditransitive/>
<transitive/>
</word>
<word>
<base>abbey</base>
<category>noun</category>
<id>E0203496</id>
</word>
<word>
<base>ability</base>
<category>noun</category>
<id>E0006490</id>
</word>
<word>
<base>able</base>
<category>adjective</category>
<id>E0006510</id>
<predicative/>
<qualitative/>
</word>
<word>
<base>abnormal</base>
<category>adjective</category>
<id>E0006517</id>
<predicative/>
<qualitative/>
</word>
<word>
<base>abolish</base>
<category>verb</category>
<id>E0006524</id>
<transitive/>
</word>
</lexicon>
Мне нужно прочитать этот файл с помощью приложения С#, и если только category
есть verb
, я хочу напечатать весь его элемент word
.
Как я могу это сделать?
Ответы
Ответ 1
Вы можете использовать linq для xml.
var xmlStr = File.ReadAllText("fileName.xml");
var str = XElement.Parse(xmlStr);
var result = str.Elements("word").
Where(x => x.Element("category").Value.Equals("verb")).ToList();
Console.WriteLine(result);
Ответ 2
Вы можете использовать XPath. Немного старомодный, но все же эффективный:
using System.Xml;
...
XmlDocument xmlDocument;
xmlDocument = new XmlDocument();
xmlDocument.LoadXml(xml);
foreach (XmlElement xmlElement in
xmlDocument.DocumentElement.SelectNodes("word[category='verb']"))
{
Console.Out.WriteLine(xmlElement.OuterXml);
}
Ответ 3
XDocument xdoc = XDocument.Load(path_to_xml);
var word = xdoc.Elements("word")
.SingleOrDefault(w => (string)w.Element("category") == "verb");
Этот запрос вернет цельное слово XElement
. Если имеется более одного элемента слова с категорией verb
, вы получите InvalidOperationException
. Если элементов с категорией verb
нет, результат будет null
.
Ответ 4
Вот как я это сделал (приведенный ниже код был протестирован, полный источник предоставлен ниже), начните с создания класса с общими свойствами
class Word
{
public string Base { get; set; }
public string Category { get; set; }
public string Id { get; set; }
}
загрузите с помощью XDocument с INPUT_DATA для демонстрационных целей и найдите имя элемента с лексикой.,.
XDocument doc = XDocument.Parse(INPUT_DATA);
XElement lex = doc.Element("lexicon");
убедитесь, что есть значение, и используйте linq для извлечения из него элементов слова.,.
Word[] catWords = null;
if (lex != null)
{
IEnumerable<XElement> words = lex.Elements("word");
catWords = (from itm in words
where itm.Element("category") != null
&& itm.Element("category").Value == "verb"
&& itm.Element("id") != null
&& itm.Element("base") != null
select new Word()
{
Base = itm.Element("base").Value,
Category = itm.Element("category").Value,
Id = itm.Element("id").Value,
}).ToArray<Word>();
}
Оператор where
проверяет, существует ли элемент категории и что значение категории не равно null, а затем снова проверьте его, что это глагол. Затем проверьте, что другие узлы также существуют.,.
Запрос linq вернет IEnumerable <Typename> , поэтому мы можем вызвать ToArray <Typename> (), чтобы вывести всю коллекцию в желаемый тип.
Затем распечатайте его, чтобы получить.,
[Found]
Id: E0006429
Base: abandon
Category: verb
[Found]
Id: E0006524
Base: abolish
Category: verb
Полный исходный код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace test
{
class Program
{
class Word
{
public string Base { get; set; }
public string Category { get; set; }
public string Id { get; set; }
}
static void Main(string[] args)
{
XDocument doc = XDocument.Parse(INPUT_DATA);
XElement lex = doc.Element("lexicon");
Word[] catWords = null;
if (lex != null)
{
IEnumerable<XElement> words = lex.Elements("word");
catWords = (from itm in words
where itm.Element("category") != null
&& itm.Element("category").Value == "verb"
&& itm.Element("id") != null
&& itm.Element("base") != null
select new Word()
{
Base = itm.Element("base").Value,
Category = itm.Element("category").Value,
Id = itm.Element("id").Value,
}).ToArray<Word>();
}
//print it
if (catWords != null)
{
Console.WriteLine("Words with <category> and value verb:\n");
foreach (Word itm in catWords)
Console.WriteLine("[Found]\n Id: {0}\n Base: {1}\n Category: {2}\n",
itm.Id, itm.Base, itm.Category);
}
}
const string INPUT_DATA =
@"<?xml version=""1.0""?>
<lexicon>
<word>
<base>a</base>
<category>determiner</category>
<id>E0006419</id>
</word>
<word>
<base>abandon</base>
<category>verb</category>
<id>E0006429</id>
<ditransitive/>
<transitive/>
</word>
<word>
<base>abbey</base>
<category>noun</category>
<id>E0203496</id>
</word>
<word>
<base>ability</base>
<category>noun</category>
<id>E0006490</id>
</word>
<word>
<base>able</base>
<category>adjective</category>
<id>E0006510</id>
<predicative/>
<qualitative/>
</word>
<word>
<base>abnormal</base>
<category>adjective</category>
<id>E0006517</id>
<predicative/>
<qualitative/>
</word>
<word>
<base>abolish</base>
<category>verb</category>
<id>E0006524</id>
<transitive/>
</word>
</lexicon>";
}
}
Ответ 5
В качестве альтернативы вы можете использовать XPath запрос через XPathSelectElements
:
var document = XDocument.Parse(yourXmlAsString);
var words = document.XPathSelectElements("//word[./category[text() = 'verb']]");