Я хочу извлечь некоторую информацию из примера xml ниже. Я хочу вытащить коллекцию строк, которые содержат интересующую меня колонку.
Я не знаю, как это сделать... Я пробовал этот код, но он не работал:
XElement elem = XElement.Load("SIMC.xml");
var homePhone = from phoneno in elem.Elements("row")
where (string)phoneno.Element("col").Attribute("name") == "NAZWA"
select phoneno;
// Console.WriteLine("List HomePhone Nos.");
foreach (XElement xEle in homePhone)
{
MessageBox.Show(xEle.Element("col").Value);
}
Вот пример XML, который я пытаюсь проанализировать:
<?xml version="1.0" encoding="UTF-8"?>
<teryt>
<catalog name="SIMC" type="all" date="2015-01-01">
<row>
<col name="WOJ">18</col>
<col name="POW">16</col>
<col name="GMI">13</col>
<col name="RODZ_GMI">2</col>
<col name="RM">00</col>
<col name="MZ">1</col>
<col name="NAZWA">Na Polu</col>
<col name="SYM">0664326</col>
<col name="SYMPOD">0664310</col>
<col name="STAN_NA">2015-01-01</col>
</row>
<row>
<col name="WOJ">28</col>
<col name="POW">06</col>
<col name="GMI">05</col>
<col name="RODZ_GMI">2</col>
<col name="RM">03</col>
<col name="MZ">1</col>
<col name="NAZWA">Majerka</col>
<col name="SYM">0761615</col>
<col name="SYMPOD">0761609</col>
<col name="STAN_NA">2015-01-01</col>
</row>
<row>
<col name="WOJ">12</col>
<col name="POW">09</col>
<col name="GMI">03</col>
<col name="RODZ_GMI">5</col>
<col name="RM">00</col>
<col name="MZ">1</col>
<col name="NAZWA">Pod Kamiennikiem</col>
<col name="SYM">0328485</col>
<col name="SYMPOD">0328456</col>
<col name="STAN_NA">2015-01-01</col>
</row>
<row>
<col name="WOJ">32</col>
<col name="POW">17</col>
<col name="GMI">04</col>
<col name="RODZ_GMI">5</col>
<col name="RM">01</col>
<col name="MZ">1</col>
<col name="NAZWA">Miłogoszcz</col>
<col name="SYM">0530732</col>
<col name="SYMPOD">0530732</col>
<col name="STAN_NA">2015-01-01</col>
</row>
Я хочу извлечь элементы строки, где есть столбец с name
атрибута, равным NAZWA
и значением столбца Miłogoszcz
.
Мой код пока ничего не показывает
Если мы думаем об этой проблеме интуитивно, что мы действительно хотим, так это:
Верните строки, где есть столбец в этой строке, который имеет атрибут "имя" с определенным значением и значением столбца с определенным значением.
Предположим, что у нас уже есть IEnumerable<XElement> rows
которые представляют элементы строки XML файла. Затем мы могли выбрать только те строки, которые нам нужны, используя методы расширения LINQ. Здесь может выглядеть одна такая функция.
public static IEnumerable<XElement> GetRowsWithColumn(IEnumerable<XElement> rows, String name, String value)
{
return rows
.Where(row => row.Elements("col") //Get Columns
.Any(col => //This column should...
col.Attributes("name").Any(attr => attr.Value.Equals(name)) //have the right name attribute
&& col.Value.Equals(value))); //and have the right value
}
Вот полная программа, которая, я считаю, делает то, что вы просите. Он открывает файл и затем исследует элементы, возвращая строки, где есть подэлемент "col", который имеет имя атрибута со значением NAZWA
и этот столбец имеет значение Miłogoszcz
Этот код использует функцию, которую мы написали выше, чтобы вы могли подключить все, что хотите, для атрибута имени столбца и значения столбца.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace StackOverflowTest
{
class Program
{
public static IEnumerable<XElement> GetRowsWithColumn(IEnumerable<XElement> rows, String name, String value)
{
return rows
.Where(row => row.Elements("col")
.Any(col =>
col.Attributes("name").Any(attr => attr.Value.Equals(name))
&& col.Value.Equals(value)));
}
static void Main(string[] args)
{
//Load file
XElement elem = XElement.Load("./test.xml");
//Get Rows
var rows = elem
.Elements("catalog")
.Elements("row");
//Filter rows
var interestingRows = GetRowsWithColumn(rows, "NAZWA", "Miłogoszcz");
//Print rows
foreach (var row in interestingRows)
{
//This is MessageBox.Show in your example
Console.WriteLine(row);
}
Console.Read();
}
}
}
Надеюсь, это решит вашу проблему. Дай мне знать, если я пропустил что-нибудь.
Обратите внимание, что я действительно изменил ваш XML файл, чтобы быть допустимым, включив блоки закрытия для элементов верхнего уровня
<?xml version="1.0" encoding="UTF-8"?>
<teryt>
<catalog name="SIMC" type="all" date="2015-01-01">
<row>
<col name="WOJ">18</col>
<col name="POW">16</col>
<col name="GMI">13</col>
<col name="RODZ_GMI">2</col>
<col name="RM">00</col>
<col name="MZ">1</col>
<col name="NAZWA">Na Polu</col>
<col name="SYM">0664326</col>
<col name="SYMPOD">0664310</col>
<col name="STAN_NA">2015-01-01</col>
</row>
<row>
<col name="WOJ">28</col>
<col name="POW">06</col>
<col name="GMI">05</col>
<col name="RODZ_GMI">2</col>
<col name="RM">03</col>
<col name="MZ">1</col>
<col name="NAZWA">Majerka</col>
<col name="SYM">0761615</col>
<col name="SYMPOD">0761609</col>
<col name="STAN_NA">2015-01-01</col>
</row>
<row>
<col name="WOJ">12</col>
<col name="POW">09</col>
<col name="GMI">03</col>
<col name="RODZ_GMI">5</col>
<col name="RM">00</col>
<col name="MZ">1</col>
<col name="NAZWA">Pod Kamiennikiem</col>
<col name="SYM">0328485</col>
<col name="SYMPOD">0328456</col>
<col name="STAN_NA">2015-01-01</col>
</row>
<row>
<col name="WOJ">32</col>
<col name="POW">17</col>
<col name="GMI">04</col>
<col name="RODZ_GMI">5</col>
<col name="RM">01</col>
<col name="MZ">1</col>
<col name="NAZWA">Miłogoszcz</col>
<col name="SYM">0530732</col>
<col name="SYMPOD">0530732</col>
<col name="STAN_NA">2015-01-01</col>
</row>
</catalog>
</teryt>
Вам нужно либо использовать Descendents
либо правильно следовать иерархии XML, вы пропускаете два уровня в своей логике. Я также изменил (string)
на .Value
чтобы работать правильно.
XElement elem = XElement.Load("SIMC.xml");
var homePhone = from phoneno in elem.Elements("teryt")
.Elements("catalog")
.Elements("row")
where phoneno.Elements("col")
.Any(xelm =>
xelm.Attribute("name").Value == "NAZWA" &&
xelm.Value == "Miłogoszcz")
select phoneno;
// Console.WriteLine("List HomePhone Nos.");
foreach (XElement xEle in homePhone)
{
//Note that you need to decide how to format this
MessageBox.Show(string.Join(", ",
xEle.Select(x => x.Attribute("name").Value + "=" + x.Value));
}
<row>
на данный момент.