Как я могу отфильтровать разделы XML и сохранить его в виде файла - PullRequest
2 голосов
/ 16 января 2011

Я новичок в использовании LINQ. У меня есть данные XML в формате ниже

<Root>
    <Global>
    </Global>
    <local>
        <element name="A">
            <subelement name="A">
                <element name="A1">
                    <subelement name="A1">
                        <Property>
                        </Property>
                    </subelement>
                </element>
                <element name="B">
                    <Property>
                    </Property>
                </element>
            </subelement>
            <subelement name="B">
                <element name="A">
                    <Property>
                    </Property>
                </element>
                <element name="B">
                    <Property>
                    </Property>
                </element>
            </subelement>
        </element>
    </local>
</Root>

Я хочу сохранить каждый раздел элемента Property в своем собственном XML-файле, как показано ниже, сохранив при этом структуру иерархии в неизменном виде

<Root>
    <Global>
    </Global>
    <local>
        <element name="A">
            <subelement name="A">
                <element name="A1">
                    <subelement name="A1">
                        <Property>
                        </Property>
                </subelement>
                </element>
            </subelement>
        </element>
    </local>
</Root>

и

<Root>
    <Global>
    </Global>
    <local>
        <element name="A">
            <subelement name="A">
                <element name="B">
                    <Property>
                    </Property>
                </element>
            </subelement>
        </element>
    </local>
</Root>

и т. Д. Для всех элементов Property . Каждый элемент может иметь дочерний субэлемент , а каждый субэлемент может иметь элемент дочерний

Можете ли вы предоставить решение о том, как сохранить каждый раздел элемента Свойство в виде нового XML-файла с неизменной структурой текущей иерархии. Я пытался использовать метод Ancestor () класса XElement

XDocument xml = XDocument.Load(filename);
XDocument convertedQuery = new XDocument(
        new XElement(xml.Root.Name, from x in xml.Descendants("local")
                                    select x.Ancestors())
         );

но он возвращает и другие свойства элементов, как показано ниже

<Root>
<Global></Global>
<local>
  <element name="A">
    <subelement name="A">
      <element name="A1">
        <subelement name="A1">
          <Property></Property>
        </subelement>
      </element>
      <element name="B">
        <Property></Property>
      </element>
    </subelement>
    <subelement name="B">
      <element name="A">
        <Property></Property>
      </element>
      <element name="B">
        <Property></Property>
      </element>
    </subelement>
  </element>
</local>

Любая помощь будет высоко ценится. Спасибо

1 Ответ

2 голосов
/ 16 января 2011

Вот пример C #, который должен делать то, что вы хотите, или, по крайней мере, дать вам представление о том, как к этому подойти.Образец для тестирования просто записывает каждый созданный XDocument в Console.Out, но, конечно, вы можете изменить это, чтобы сохранить в файл на диске:

static void Main(string[] args)
{
    XDocument doc = XDocument.Load(@"..\..\XMLFile1.xml");
    foreach (XElement prop in doc.Descendants("Property"))
    {
        XDocument result = new XDocument(
            new XElement(doc.Root.Name, doc.Root.Attributes(),
                doc.Root.Elements("Global"),
                CopySubtree(prop.Ancestors("local").First(), prop)));
        result.Save(Console.Out);
        Console.WriteLine();
    }
}
static XElement CopySubtree(XElement ancestor, XElement descendant)
{
    if (ancestor == descendant)
    {
        return descendant;
    }
    else
    {
        return
            new XElement(
                ancestor.Name, 
                ancestor.Attributes(), 
                CopySubtree(
                  ancestor
                  .Elements()
                  .First(e => e.DescendantsAndSelf().Any(d => d == descendant)),
                  descendant));
    }
}

[править] Для нового требования копировать не толькоСвойство предков, а также его братьев и сестер вы можете адаптировать вышеуказанным способом следующим образом:

static XElement CopySubtree(XElement ancestor, XElement descendant)
{
    if (ancestor == descendant.Parent)
    {
        return ancestor;
    }
    else
    {
        return
            new XElement(
                ancestor.Name, 
                ancestor.Attributes(), 
                CopySubtree(
                  ancestor
                  .Elements()
                  .First(e => e.DescendantsAndSelf().Any(d => d == descendant)),
                  descendant));
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...