如何从 StringBuilder C 创建具有多个根的 XML 文件#

How to create an XML file with several roots from a StringBuilder C#

提问人:Cesar 提问时间:10/4/2023 最后编辑:Cesar 更新时间:10/4/2023 访问量:88

问:

我是一名机械师,必须开发工具来管理 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() 替换为正确的格式。 不遵守断线,并在我的字符串中添加内容。该文件是无用的。 我得到的就在下面:

&lt;MLlibXMLCommand message_level="warning" command="merge"&gt;&lt;Inputs&gt;&lt;File iref="0000ancv" name="source\APS4322_TileCalibrations.bml" / /&gt;&lt;File iref="0000and1" name="source\APS4322_TileCalibrations.bml" /&gt;&lt;File iref="0000anct" name="source\APS4322_TileCalibrations.bml" /&gt;&lt;File iref="0000and1" name="source\APS4322_TileCalibrations.bml" /&gt;&lt;/Inputs&gt;&lt;Outputs&gt;&lt;File name="target\merged.bml" type="bml" /&gt;&lt;/Outputs&gt;&lt;/MLlibXMLCommand&gt;&lt;MLlibXMLCommand message_level="warning" command="convert" output_model="special_transformation"&gt;&lt;Inputs&gt;&lt;File name="target\merged.bml" type="bml" /&gt;&lt;/Inputs&gt;&lt;Outputs&gt;&lt;File name="target\XPlanar_TileCalibrations.bml" type="bml" /&gt;&lt;/Outputs&gt;&lt;/MLlibXMLCommand&gt;

第二种解决方案是使用 .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");

C# XML 文件 stringbuilder xmlDocument

评论

0赞 Jon Skeet 10/4/2023
请花一些时间阅读 stackoverflow.com/editing-help 上的格式指南 - 您的问题目前真的很难阅读。目前还不清楚你到底要实现什么 - 如果你能提供一个简短的示例“不是真正的 XML”文件,以及预期的输出和实际输出,这将使你更容易帮助你。
0赞 Fildor 10/4/2023
这是否类似于XML等同于jsonlines
0赞 Cesar 10/4/2023
我编辑它是为了更清晰
0赞 jdweng 10/4/2023
将以下内容添加到您的 Xml 设置中:settingsw。Ident = 真;

答:

2赞 max 10/4/2023 #1

如果您需要使用 XML 节点,那么最好切换到 linq-to-XML(命名空间),因为使用旧的 .System.Xml.LinqXmlDocument

您可以加载 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");

评论

0赞 Cesar 10/4/2023
谢谢你的回答。我已经试过这个:System.IO.File.WriteAllText(“output.xml”, sb。ToString());但是所有数据都只写在文件中的一行中。我将尝试您的第二种解决方案,方法是在两个不同的节点中获取数据,然后使用这两个节点重建文件