Копирование части одного XML DOM в другой для преобразования XSL (.NET) - PullRequest
0 голосов
/ 22 июля 2009

Область применения XML и DOM в .NET 3.5 настолько велика, что у меня возникают проблемы с поиском простого решения моей проблемы без использования слишком большого количества беспорядочного кода. Поскольку люди здесь всегда находят элегантные решения, я подумал, что это будет хороший вопрос.

Как мне взять XML-файл (который я создал и сохранил ранее в программе), в котором есть n экземпляров узла «unit» под корневым узлом «report», чтобы создать XML DOM с «report» значения и одна «единица».

Мне нужно сделать это для каждого модуля, а затем создать файл HTML, используя мою существующую таблицу стилей преобразования XSL в новых XML DOM. Я уже могу заставить его работать для всех единиц (существующий файл XML), но мне нужен отчет для каждой единицы.

РЕДАКТИРОВАТЬ (за запрос комментария):

Как это выглядит:

<report>
  <report_name>Name</report_name>
  <report_date>yyyy/mm/dd</report_date>
  <unit>
    <ip>127.0.0.1</ip>
    <label>localhost</label>
    ..etc
  </unit>
  <unit>
    <ip>255.255.255.255</ip>
    <label>broadcast</label>
    ..etc
  </unit>
<report>

И я хочу каждый из:

<report>
  <report_name>Name</report_name>
  <report_date>yyyy/mm/dd</report_date>
  <unit>
    <ip>127.0.0.1</ip>
    <label>localhost</label>
    ..etc
  </unit>
</report>

и

<report>
  <report_name>Name</report_name>
  <report_date>yyyy/mm/dd</report_date>
  <unit>
    <ip>255.255.255.255</ip>
    <label>broadcast</label>
    ..etc
  </unit>
<report>

Ответы [ 2 ]

1 голос
/ 22 июля 2009
foreach (XmlElement xmlUnit in xmlMain.SelectNodes("/report/unit"))
{
    var xmlDest = new XmlDocument();
    xmlDest.AppendChild(xmlDest.CreateElement("report"));

    // Add the report properties...
    foreach ( XmlElement xmlValue in xmlMain.SelectNodes( "/report/report_name | /report/report_date" ) )
        xmlDest.DocumentElement.AppendChild(xmlDest.ImportNode(xmlValue, true));

    // Add the "<unit>" element from the main document...
    xmlDest.DocumentElement.AppendChild(xmlDest.ImportNode(xmlUnit, true));

    // Now generate report using xmlDest
}
0 голосов
/ 22 июля 2009

Если вам не нужен доступ к информации вне элемента unit, вы можете сделать это:

foreach (XmlNode n in d.SelectNodes("/report/unit"))
{
   using (StringReader sr = new StringReader(n.OuterXml))
   using (XmlReader xr = XmlReader.Create(sr))
   using (XmlWriter xw = XmlWriter.Create(Console.Out))
   {
       xslt.Transform(xr, xw);
   }
}

Недостатком этого подхода является то, что XSLT может получить доступ только к XML в выбранном узле. Если вам нужен доступ к XML в другом месте документа, вам нужно указать преобразованию, какой узел обрабатывать:

for (int i = 0; i < d.SelectNodes("/report/unit").Count; i++)
{
    XsltArgumentList args = new XsltArgumentList();
    args.AddParam("position", "", i + 1);
    using (StringReader sr = new StringReader(d.OuterXml))
    using (XmlReader xr = XmlReader.Create(sr))
    using (XmlWriter xw = XmlWriter.Create(Console.Out))
    {
        xslt.Transform(xr, args, xw);
    }
}

... и пусть ваш XSLT включает в себя:

<xsl:param name="position"/>
<xsl:template match="/">
    <xsl:apply-templates select="/report/unit[$position=position()]"/>
</xsl:template>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...