如何使用 C# 通过读取另一个 XML 文件来创建 XML 文档?
Posted
技术标签:
【中文标题】如何使用 C# 通过读取另一个 XML 文件来创建 XML 文档?【英文标题】:How do you create XML document from reading another XML file using C#? 【发布时间】:2021-12-14 03:33:21 【问题描述】:我正在尝试重新创建一个 xml 文档。 我正在阅读现有的 xml 文档,然后尝试使用 C# 重新创建它。
到目前为止,我能够阅读并创建新文档的外壳。
我正在遍历每个子节点并将其添加到产品节点。
我的 xml 文件(来源):
<?xml version="1.0" encoding="utf-8"?>
<DroneList>
<product>
<manufacturer>DJI</manufacturer>
<modelName>Phantom 3</modelName>
<estimatedPrice>699</estimatedPrice>
<flightTime>17 to 20</flightTime>
<modelSize>Medium</modelSize>
</product>
<product>
<manufacturer>DJI</manufacturer>
<modelName>Inspire 1</modelName>
<estimatedPrice>2899</estimatedPrice>
<flightTime>18 to 20</flightTime>
<modelSize>Large</modelSize>
</product>
</DroneList>
注意:根目录下有多个具有唯一项的产品。
我使用 C# 程序的目标是能够:
从列表中读取现有产品 将它们添加到新的 xml 文档中 向新的 xml 文档添加新项目 将 xml 文档另存为新的 xml 文件我的 C# 代码如下:
private void btnChange_Click(object sender, EventArgs e)
txtDisplay.Clear();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(XML_FILE_PATH); // load xml data
XmlDocument newDoc = new XmlDocument(); // create a new xmldocument object to hold new xml data
txtDisplay.Text += "****Reading Drone List**** \r\n";
// loaded existing xml data
XmlElement root = xmlDoc.DocumentElement;
XmlNodeList children = root.ChildNodes;
txtDisplay.Text += "****Showing Existing Data**** \r\n children: " + children.Count + "\r\n";
for (int i = 0; i < children.Count; i++)
XmlElement product = newDoc.CreateElement("product");
product.SetAttribute("productId", i.ToString());
foreach (XmlNode child in children)
XmlElement manufacturer = newDoc.CreateElement("manufacturer");
XmlElement modelName = newDoc.CreateElement("modelName");
XmlElement estimatedPrice = newDoc.CreateElement("estimatedPrice");
XmlElement flightTime = newDoc.CreateElement("flightTime");
XmlElement modelSize = newDoc.CreateElement("modelSize");
manufacturer.InnerText = child["manufacturer"].InnerText;
modelName.InnerText = child["modelName"].InnerText;
estimatedPrice.InnerText = child["estimatedPrice"].InnerText;
flightTime.InnerText = child["flightTime"].InnerText;
modelSize.InnerText = child["modelSize"].InnerText;
product.AppendChild(manufacturer);
product.AppendChild(modelName);
product.AppendChild(estimatedPrice);
product.AppendChild(flightTime);
product.AppendChild(modelSize);
txtDisplay.Text += "****Showing new doc so far**** \r\n";
txtDisplay.Text += newDoc.InnerXml + "\r\n"; // display xml in the textbox
//txtDisplay.Text += newRoot.InnerText + "\r\n";
txtDisplay.Text += "****Adding New Data**** \r\n";
for (int i = 5; i < 5; i++)
//
XmlElement newRoot = newDoc.CreateElement("DroneList"); // the root element is <roster>
newDoc.AppendChild(newRoot);
XmlDeclaration xmlDec = newDoc.CreateXmlDeclaration("1.0", null, null);
newDoc.InsertBefore(xmlDec, newRoot); // insert before the root element
newDoc.Save("..\\..\\..\\new_drones.xml");
所需的 XML 结果:
新的 xml 文件(目标)
<?xml version="1.0" encoding="utf-8"?>
<DroneList>
<!-- existing products from source file -->
<product>
<manufacturer>DJI</manufacturer>
<modelName>Phantom 3</modelName>
<estimatedPrice>699</estimatedPrice>
<flightTime>17 to 20</flightTime>
<modelSize>Medium</modelSize>
</product>
<product>
<manufacturer>DJI</manufacturer>
<modelName>Inspire 1</modelName>
<estimatedPrice>2899</estimatedPrice>
<flightTime>18 to 20</flightTime>
<modelSize>Large</modelSize>
</product>
<!-- new products added through C# program (Hard coded) -->
<product>
<manufacturer>DJI</manufacturer>
<modelName>Inspire 1</modelName>
<estimatedPrice>2899</estimatedPrice>
<flightTime>18 to 20</flightTime>
<modelSize>Large</modelSize>
</product>
<product>
<manufacturer>DJI</manufacturer>
<modelName>Inspire 1</modelName>
<estimatedPrice>2899</estimatedPrice>
<flightTime>18 to 20</flightTime>
<modelSize>Large</modelSize>
</product>
<product>
<manufacturer>DJI</manufacturer>
<modelName>Inspire 1</modelName>
<estimatedPrice>2899</estimatedPrice>
<flightTime>18 to 20</flightTime>
<modelSize>Large</modelSize>
</product>
</DroneList>
【问题讨论】:
请在您的问题中添加所需的输出 XML。总的来说,这听起来像是 XSLT 的一项任务。 如果是我,我会 (1) 反序列化为 c# 对象,(2) 编写代码以添加到对象的列表,(3) 反序列化回 xml。 @YitzhakKhabinsky 我已经用期望的结果更新了问题。 使用专为这项工作设计的 XSLT,这种事情要容易得多。 【参考方案1】:总体而言,XSLT 的设计目的是将输入 XML 转换为输出 XML,或其他文本格式。
请尝试以下基于 XSLT 的解决方案。
XSLT 采用最后一个 product 元素并将其乘以 4 次。 输入 XML 的其余部分保持不变。
下面的 c# 代码是 XSLT 转换的通用样板代码。
输入 XML
<?xml version="1.0"?>
<DroneList>
<product>
<manufacturer>DJI</manufacturer>
<modelName>Phantom 3</modelName>
<estimatedPrice>699</estimatedPrice>
<flightTime>17 to 20</flightTime>
<modelSize>Medium</modelSize>
</product>
<product>
<manufacturer>DJI</manufacturer>
<modelName>Inspire 1</modelName>
<estimatedPrice>2899</estimatedPrice>
<flightTime>18 to 20</flightTime>
<modelSize>Large</modelSize>
</product>
</DroneList>
XSLT 1.0
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="no"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="product[last()]">
<xsl:variable name="product">
<xsl:copy-of select="."/>
</xsl:variable>
<xsl:for-each select="(//node())[4 >= position()]">
<xsl:copy-of select="$product"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
输出 XML
<?xml version="1.0" encoding="utf-8"?>
<DroneList>
<product>
<manufacturer>DJI</manufacturer>
<modelName>Phantom 3</modelName>
<estimatedPrice>699</estimatedPrice>
<flightTime>17 to 20</flightTime>
<modelSize>Medium</modelSize>
</product>
<product>
<manufacturer>DJI</manufacturer>
<modelName>Inspire 1</modelName>
<estimatedPrice>2899</estimatedPrice>
<flightTime>18 to 20</flightTime>
<modelSize>Large</modelSize>
</product>
<product>
<manufacturer>DJI</manufacturer>
<modelName>Inspire 1</modelName>
<estimatedPrice>2899</estimatedPrice>
<flightTime>18 to 20</flightTime>
<modelSize>Large</modelSize>
</product>
<product>
<manufacturer>DJI</manufacturer>
<modelName>Inspire 1</modelName>
<estimatedPrice>2899</estimatedPrice>
<flightTime>18 to 20</flightTime>
<modelSize>Large</modelSize>
</product>
<product>
<manufacturer>DJI</manufacturer>
<modelName>Inspire 1</modelName>
<estimatedPrice>2899</estimatedPrice>
<flightTime>18 to 20</flightTime>
<modelSize>Large</modelSize>
</product>
</DroneList>
c#
oid Main()
const string SOURCEXMLFILE = @"e:\Temp\input.xml";
const string XSLTFILE = @"e:\Temp\process.xslt";
const string OUTPUTXMLFILE = @"e:\temp\output.xml";
try
XsltArgumentList xslArg = new XsltArgumentList();
using (XmlReader src = XmlReader.Create(SOURCEXMLFILE))
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(XSLTFILE, new XsltSettings(true, true), new XmlUrlResolver());
XmlWriterSettings settings = xslt.OutputSettings.Clone();
settings.IndentChars = "\t";
// to remove BOM
settings.Encoding = new UTF8Encoding(false);
using (XmlWriter result = XmlWriter.Create(OUTPUTXMLFILE, settings))
xslt.Transform(src, xslArg, result, new XmlUrlResolver());
result.Close();
Console.WriteLine("File '0' has been generated.", OUTPUTXMLFILE);
catch (Exception ex)
Console.WriteLine(ex.Message);
【讨论】:
@Yizhak 我只需要使用 C# 执行此操作。我不能使用 XSLT 或除 XML DOM 之外的任何其他方法,也不能使用元素和节点系统地分解它。 XSLT 是 .Net 框架的一部分。那么有什么问题呢?以上是关于如何使用 C# 通过读取另一个 XML 文件来创建 XML 文档?的主要内容,如果未能解决你的问题,请参考以下文章