.NET 3.5中的XML和DOM的范围非常大,以至于我无法使用简单的解决方案来解决我的问题,而不会使用太多的乱码代码。由于这里的人总是提出一些优雅的解决方案,我认为这将是一个很好的问题。
如何接收在根“报告”节点下具有n个“单元”节点实例的XML文件(我在程序中先前创建并保存),以创建具有“报告”的XML DOM价值观和一个'单位'。
我需要为每个单元执行此操作,然后使用新XML DOM上的现有XSL转换样式表创建HTML文件。我已经可以让它适用于所有单元(现有的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>
答案 0 :(得分:1)
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
}
答案 1 :(得分:0)
如果您不需要访问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>