Often we find ourselves having to transform the XML file given to us. Yes, it would be great if everyone subscribed to the same structure, but in a mid- to large-sized company this can be more difficult to achieve.
I started with your XML file:
<?xml version="1.0" encoding="utf-8" ?>
<TestFile>
<string>Foo</string>
<bool>false</bool>
<bool>true</bool>
<string>Bar</string>
</TestFile>
Then created the transform file (this is just an example and is all up to your own preference):
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<ParameterCollection>
<xsl:apply-templates select="@* | node()"/>
</ParameterCollection>
</xsl:copy>
</xsl:template>
<xsl:template match="bool">
<Parameter type="bool">
<xsl:apply-templates select="node()"/>
</Parameter>
</xsl:template>
<xsl:template match="string">
<Parameter type="string">
<xsl:apply-templates select="node()"/>
</Parameter>
</xsl:template>
</xsl:stylesheet>
Then I started piecing all the necessary classes together:
[XmlRootAttribute("TestFile", IsNullable = false)]
public class TestFile
{
[XmlArrayAttribute("ParameterCollection")]
public Parameter[] Parameters;
}
public class Parameter
{
[XmlAttribute("type")]
public string ObjectType;
[XmlText]
public string ObjectValue;
}
Then apply everything (hopefully in a more thoughtful manner than I have done):
class Program
{
static void Main(string[] args)
{
FileInfo xmlFile = new FileInfo(@"Resources\TestFile.xml");
FileInfo transformFile = new FileInfo(@"Resources\TestFileTransform.xslt");
FileInfo prettyFile = new FileInfo(@"Resources\PrettyFile.xml");
if (xmlFile.Exists && transformFile.Exists)
{
// Perform transform operations.
XslCompiledTransform trans = new XslCompiledTransform();
trans.Load(transformFile.FullName);
trans.Transform(xmlFile.FullName, prettyFile.FullName);
}
if (prettyFile.Exists)
{
// Deserialize the new information.
XmlSerializer serializer = new XmlSerializer(typeof(TestFile));
XDocument doc = XDocument.Load(prettyFile.FullName);
TestFile o = (TestFile)serializer.Deserialize(doc.CreateReader());
// Show the results.
foreach (Parameter p in o.Parameters)
{
Console.WriteLine("{0}: {1}", p.ObjectType, p.ObjectValue);
}
}
// Pause for effect.
Console.ReadKey();
}
}
Hopefully this helps someone, or at least gives them another option. Typically, IMHO I would prefer to parse the file or stream, but that is just me.