I'm a mechanician who has to develop tools yo manage xml files.
I have an issue and I need your help.
One of my xml file that I have to manage has several roots. Don't ask why, my provider will not change...
Below, the file i have loaded in a StringBuilder and I want to save it in a 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>
I can't use the XmlDocument.Load(myStringBuilder) to save it in a new file (because of several roots).
I tried XmlWriter with fragment exception setting but I didn't succeed to write.MyStringBuilder() with the correct format. Break lines are not respected and things are added in my String. The file is useless. What i get is just below :
<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>
Second solution is to used .WriteAllText but break lines are not respected. File I get which is no correct :
<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>
I don't know if I'm not using the right tool, or if I'm missing one or if my way of making it is bad.
Thank you in advance if you can unlock this step in my program process (the step consist to save myStringBuilder in a file like test.xml) .
I tried, and nothing is working properly :
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");
If you need to work with XML nodes then it is probably better to switch to linq-to-XML (
System.Xml.Linqnamespace), because it is harder to work with XML fragments like that with oldXmlDocument.You can load XML fragments (as a list of nodes, since
XDocumentrequires single root):LoadNodesFromXML()can be used to load XML from string, likeAnd save them:
If you need more control over formatting, like inserting an empty line between nodes (like in original example), you can create
StreamWriterexplicilty:You can even take
XDocumentand ignore its root element, producing multi-root file: