提问人:Cesar 提问时间:10/4/2023 最后编辑:Cesar 更新时间:10/4/2023 访问量:88
如何从 StringBuilder C 创建具有多个根的 XML 文件#
How to create an XML file with several roots from a StringBuilder C#
问:
我是一名机械师,必须开发工具来管理 xml 文件。
我有一个问题,我需要你的帮助。
我必须管理的一个 xml 文件有几个根目录。不要问为什么,我的提供者不会改变......
下面,我在 StringBuilder 中加载的文件,我想将其保存在 file.xml 中
<MLlibXMLCommand message_level='warning' command='merge'>
<Inputs>
<File iref='0000ancv' name='source\APS4322_TileCalibrations.bml'/>
</Inputs>
<Outputs>
<File name='target\merged.bml' type='bml' />
</Outputs>
</MLlibXMLCommand>
<MLlibXMLCommand message_level='warning' command='convert' output_model='special_transformation'>
<Inputs>
<File name='target\merged.bml' type='bml'/>
</Inputs>
<Outputs>
<File name='target\XPlanar_TileCalibrations.bml' type='bml'/>
</Outputs>
</MLlibXMLCommand>
我无法使用 XmlDocument.Load(myStringBuilder) 将其保存在新文件中(因为有几个根目录)。
我尝试了带有片段异常设置的 XmlWriter,但没有成功写入。MyStringBuilder() 替换为正确的格式。 不遵守断线,并在我的字符串中添加内容。该文件是无用的。 我得到的就在下面:
<MLlibXMLCommand message_level="warning" command="merge"><Inputs><File iref="0000ancv" name="source\APS4322_TileCalibrations.bml" / /><File iref="0000and1" name="source\APS4322_TileCalibrations.bml" /><File iref="0000anct" name="source\APS4322_TileCalibrations.bml" /><File iref="0000and1" name="source\APS4322_TileCalibrations.bml" /></Inputs><Outputs><File name="target\merged.bml" type="bml" /></Outputs></MLlibXMLCommand><MLlibXMLCommand message_level="warning" command="convert" output_model="special_transformation"><Inputs><File name="target\merged.bml" type="bml" /></Inputs><Outputs><File name="target\XPlanar_TileCalibrations.bml" type="bml" /></Outputs></MLlibXMLCommand>
第二种解决方案是使用 .WriteAllText,但不考虑换行符。 我得到的文件不正确:
<MLlibXMLCommand message_level="warning" command="merge"><Inputs><File iref="0000ancv" name="source\APS4322_TileCalibrations.bml" /><File/></Inputs><Outputs><File name="target\merged.bml" type="bml" /></Outputs></MLlibXMLCommand><MLlibXMLCommand message_level="warning" command="convert" output_model="special_transformation"><Inputs><File name="target\merged.bml" type="bml" /></Inputs><Outputs><File name="target\XPlanar_TileCalibrations.bml" type="bml" /></Outputs></MLlibXMLCommand>
我不知道我是否没有使用正确的工具,或者我是否缺少一个工具,或者我的制作方式是否糟糕。
如果您可以在我的程序过程中解锁此步骤,请提前感谢您(该步骤包括将myStringBuilder保存在test.xml之类的文件中)。
我试过了,但没有任何工作正常:
StringBuilder sb = new
StringBuilder(FormatTileCalibrationXml.InnerXml);
StringBuilder sb1 = new
StringBuilder(FormatTileCalibrationXml.OuterXml);
sb.Remove(0, 6); //remove first root
int length = sb.Length - 7;
sb.Remove(length, 7); // remove last root
//Solution 1 to create the xml file with the stringbuilder as source
XmlWriterSettings settingsw = new XmlWriterSettings();
settingsw.OmitXmlDeclaration = true;
settingsw.ConformanceLevel = ConformanceLevel.Fragment;
using (XmlWriter writer = XmlWriter.Create("Test4.xml", settingsw))
{
writer.WriteString(sb.ToString());
}
//Solution 2
File.WriteAllText("Test3.xml", sb.ToString());
//Solution 3
string path = @"C:\temp\Test5.xml";
using (System.IO.StreamWriter file = new System.IO.StreamWriter(path))
{
file.Write(sb1);
}
//Solution 4
FormatTileCalibrationXml.LoadXml(sb.ToString());
FormatTileCalibrationXml.Save("Test6.xml");
答:
如果您需要使用 XML 节点,那么最好切换到 linq-to-XML(命名空间),因为使用旧的 .System.Xml.Linq
XmlDocument
您可以加载 XML 片段(作为节点列表,因为需要单个根目录):XDocument
static List<XNode> LoadNodes(XmlReader reader)
{
var nodes = new List<XNode>();
if(reader.Read())
{
while(reader.NodeType != XmlNodeType.None)
{
nodes.Add(XNode.ReadFrom(reader));
}
}
return nodes;
}
static List<XNode> LoadNodesFromXML(string xml)
{
using var textReader = new StringReader(xml);
using var reader = XmlReader.Create(textReader,
new XmlReaderSettings
{
ConformanceLevel = ConformanceLevel.Fragment,
IgnoreWhitespace = true,
});
return LoadNodes(reader);
}
static List<XNode> LoadNodesFromFile(string fileName)
{
using var reader = XmlReader.Create(fileName,
new XmlReaderSettings
{
ConformanceLevel = ConformanceLevel.Fragment,
IgnoreWhitespace = true,
});
return LoadNodes(reader);
}
LoadNodesFromXML()
可用于从字符串加载 XML,例如
var nodes1 = LoadNodesFromXML("<Child1/><Child2/>");
var nodes2 = LoadNodesFromXML(sb.ToString());
并保存它们:
static void SaveNodes(IEnumerable<XNode> nodes, string fileName)
{
using var writer = XmlWriter.Create(fileName,
new XmlWriterSettings
{
ConformanceLevel = ConformanceLevel.Fragment,
Indent = true,
});
foreach(var node in nodes)
{
node.WriteTo(writer);
}
}
如果您需要对格式进行更多控制,例如在节点之间插入空行(如原始示例中所示),则可以创建显式:StreamWriter
static void SaveNodes(IEnumerable<XNode> nodes, string fileName)
{
using var streamWriter = new StreamWriter(fileName);
using var writer = XmlWriter.Create(streamWriter,
new XmlWriterSettings
{
ConformanceLevel = ConformanceLevel.Fragment,
Indent = true,
});
foreach(var node in nodes)
{
node.WriteTo(writer);
writer.Flush();
streamWriter.WriteLine(); // empty line between nodes
}
}
您甚至可以获取并忽略其根元素,从而生成多根文件:XDocument
var doc = new XDocument(
new XElement("Root",
new XElement("Child1"),
new XElement("Child2")));
SaveNodes(doc.Root.Nodes(), "output.xml");
评论