Trying to generate objects for an XML file I have
I have an XML file, I need to extract values from it, and开发者_开发百科 put them in another XML file.
Questions:
Another person is creating the "schema" for the resulting XML file. Is there something that person can give me that will automate the inserting of the values? Do I even need to extract anything from the XML, or can something like a XSLT just do all the transformation?
Is there a problem with this XML structure below? I tried using xsd2code to generate objects but nothing will load when I use the LoadFromFileMethod - I read an article that wasn't very specific but said "nested parents" cause problems for XSD.exe and xsd2code.
<Section> <Form id="1"...> <Control id="12523"..> <--Some have this some don't <Property name="Color">Red</Property> <Property name="Size">Large</Property> </Control> </Form> <Form id="2"...> <Property name="Color">Blue</Property> <Property name="Size">Large</Property> </Form> <Form id="3"...> <Property name="Color">Red</Property> <Property name="Size">Small</Property> </Form> </Section>
Thank you for any guidance!
XSLT is the tool for XML transformation.
As far as your XML goes, in a lot of applications you should replace this:
<Property name="Color">Red</Property>
with:
<Color>Red</Color>
Some reasons:
If you want to write a schema that restricts an element's content in some way (e.g. to one of a list of values), the element must be identifiable by its name; you can't write one schema for a
Property
element with aname
attribute equals "Color" and another schema for aProperty
element whosename
attribute equals "Size".It's easier to write XPath predicates if your element names are meaningful. For instance,
Form[Color = 'Red']
is a lot easier to write (and read) thanForm[Property[@name='Color' and .='Red']]
The above is also true if you're writing Linq queries against the XML, in pretty much the same manner. Compare
Element.Descendants("Color")
withElement.Descendents("Property").Where(x => x.Attributes["name"] == "Color")
.
There are applications where it's appropriate to have generically-named elements, too; the above argument's not definitive. But if you're going to do that, you should have good reasons.
XLST is the best way to transform xml from one schema to another. Thats exactly what it was built to do. http://w3schools.com/xsl/default.asp is an excellent XSLT tutorial. All you really need is the schema, or a few examples of his xml to write your xslt file.
Also, your xml looks fine/well-formed to me.
XSLT is probably the solution if you just want to transform it, but if you need to do anything with the values in code then LINQ to Xml will make your task much easier.
I'd use XSLT for this, here's a small example to get you started.
Copy this sample code to an empty c# project:
static void Main(string[] args) {
const string xmlPath = "source.xml";
const string xslPath = "transform.xsl";
const string outPath = "out.xml";
try {
//load the Xml doc
var xmlDoc = new XPathDocument(xmlPath);
//load the Xsl
var xslDoc = new XslCompiledTransform();
xslDoc.Load(xslPath);
// create the output file
using (var outDoc = new XmlTextWriter(outPath, null)) {
//do the actual transform of Xml
xslDoc.Transform(xmlDoc, null, outDoc);
}
}
catch (Exception e) {
Console.WriteLine("Exception: {0}", e.ToString());
}
}
Write your example xml code above into source.xml file and put the following xsl code into transform.xsl file:
<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes" method="xml" />
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="Section">
<OtherSection>
<xsl:apply-templates />
</OtherSection>
</xsl:template>
<xsl:template match="Form">
<OtherForm>
<xsl:attribute name="id">
<xsl:value-of select="@id" />
</xsl:attribute>
<xsl:apply-templates />
</OtherForm>
</xsl:template>
<xsl:template match="Control">
<OtherControl>
<!-- converts id attribute to an id tag -->
<id>
<xsl:value-of select="@id" />
</id>
<xsl:apply-templates />
</OtherControl>
</xsl:template>
<xsl:template match="Property">
<OtherProperty>
<!-- converts name attribute to an id attribute -->
<xsl:attribute name="id">
<xsl:value-of select="@name" />
</xsl:attribute>
<xsl:value-of select="."/>
</OtherProperty>
</xsl:template>
</xsl:stylesheet>
The resulting out.xml should give you an idea of how the xsl is doing the work and hopefully get you started.
For more info on XSLT look up the tutorial on W3Schools.
精彩评论