I am using the XmlWriter class to create an XML document.
I am able to produce the document as required except for the root element.
I cannot seem to be able to create the the root element with the required attributes which is proving troublesome because of the namespaces and prefixes that are needed.
What I am trying to do is produce output like the following:
<prx:rootname xmlns:prx="url1" xmlns:xsi="url2" xsi:schemaLocation="url3">
The above is a condensed example of the actual root element needed, the actual URLs are quite verbose for example.
FYI, all other child elements use the same prefix as the root element.
Can I use this class or would I have to use another method to generate the desired XML output?
Related
I want to reference an XML element that is nested within an unknown amount of other elements.
For example, if I have an XML file like this:
<root>
<Example>
</Example>
</root>
And I want to add an element within the <Example> element. When I add an element within the root element I can do it like this (assuming Doc is an already defined XDocument):
Doc.Element("root").Add(new XElement("Example"));
And if there are two, I can do:
Doc.Element("root").Element("Example").Add(new XElement("newExample"))
This works fine if I know exactly what elements are going to be within what, because I can hard code it. This does not work, however, when I don't know what elements are going to be in what.
My project is a virtual folder system (makes more sense if you read this), so I don't know what elements will be nested within what. I have thought of saving the directory within the program in a List<string>, which works to store the directory, but because the only way I know how to reference elements is with hard coding every single element. Is there a way I can reference any element nested within any other element without having to hard code every parent element so I can use methods like XElement.Add()?
You can call the Descendants() method, which returns exactly that.
If you want to get a specific element with a specific path, just write a loop:
var el = root;
foreach (var name in path)
el = el.Element(name);
This is slightly different from just Schema validation. I'm asking how in C# you can check that not only is the document valid against a schema, but also validate that the schema actually applies to that document. I'd prefer a .NET / C# answer but any answer that fully respects the document standards will suffice.
I am making some assumptions as to what exactly you're looking for.
Having said "a specific schema" to me it means that you have a schema and that you're sifting through XML files trying to understand first if that schema should even be used to validate an XML.
First, I would lay some background... A "schema" could be that which one gets in a single file, or spread across multiple files. With multiple files, there are a couple of relationships possible between the XSD files: include, import, redefine; then there's the including of a schema file without a target namespace, by a schema file with a target namespace (this is typically called chameleon). So instead of "schema" I would prefer to use the term "schema set".
Some things to consider then:
A chameleon XSD in your "schema set" may not be intended to validate an XML having an unqualified document element.
A redefined XSD should not be used to validate matching XML content; the redefining XSD should.
Even though an XSD defines abc as a global element, it may not be acceptable to process XML instances that feature abc as the root element.
The above is to indicate that even though an XML may appear to implement a "specific schema", in itself it doesn't mean it matches the intent the author of the XSD placed in that schema.
Considering the above logic defined and implemented somehow, the verification I would do, as an answer to your question, would be to find the XSD definition of a non-abstract, global element - an XmlSchemaElement - in a specific XmlSchemaSet, using the full qualified name of the root element in the XML I am verifying.
System.Xml.Schema.XmlSchemaSet xset = ...; // Loaded somehow
System.Xml.XmlQualifiedName qn = ...; // LocalName + NamespaceURI
if (xset.GlobalElements.Contains(qn))
{
System.Xml.Schema.XmlSchemaElement el = (System.Xml.Schema.XmlSchemaElement)xset.GlobalElements[qn];
if (!el.IsAbstract)
{
// The XML file may implement the schemata loaded in this schema set.
}
}
I would expect this to at least help you improve your question, if I am off.
I am baffled with the behavior of the DataContractSerializer. Our configuration is XML based. XML is used as source for DataContractSerializer.ReadObject method. Recently I have encountered a problem when some properties of deserialized object were not set. I have tracked the changes and discovered that those properties were added into XML manually. Which is OK in my opinion. Apparently it was not OK in DataContractSerializer's opinion because it appears it expects XML nodes to be ordered alphabetically. Really?! Deserialization seems like really straightforward thing - read XML sequentially, parse node name, set corresponding property. What's the purpose of ordering?
Is there a workaround? Maybe some sort of settings for DataContractSerializer?
I encountered this problem recently. To work around it, I used the XmlSerializer and removed the explicit ordering from the XmlElement attributes:
set proxy_tool="C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SvcUtil.exe" /nologo /t:code /ser:XmlSerializer /UseSerializerForFaults
set sed_tool="$(ProjectDir)sed.exe" -r -i "s/,?[[:space:]]*Order=[[:digit:]]+//"
%proxy_tool% /o:"Proxy1.cs" /n:*,Namespaces.Name1 "Proxy1.wsdl"
%sed_tool% "Proxy1.cs"
%proxy_tool% /o:"Proxy2.cs" /n:*,Namespaces.Name2 "Proxy2.wsdl"
%sed_tool% "Proxy2.cs"
...
There's some more information on my blog post.
If you want to know why the order matters, it's because a sequence in XSD has a defined order, and the web service contracts are defined with XSD.
From the specification:
The consequence of this definition is that any element appearing in an instance whose type is declared to be USAddress (e.g. shipTo in po.xml) must consist of five elements and one attribute. These elements must be called name, street, city, state and zip as specified by the values of the declarations' name attributes, and the elements must appear in the same sequence (order) in which they are declared.
You can use the Order member of DataMemberAttribute to help with this, but in most cases: XML is order-specific (for elements, not attributes) - so it isn't specifically wrong.
That said: if you want fine control over XML serialization, DataContractSerializer is a poor choice XmlSerializer offers more control - and is less fussy re order iirc.
I have a dynamic XML structure. I mean, root name can be changed, element name can be changed and structure of xml can be changed.So How can I deserialize dynamic xml to objects?
Creating classes dynamically by xml element names, is this possible? If yes, then how can I do this?
So How can I deserialize this type xml to objects?
Well, you cannot deserialize a XML without a specific XSD schema to statically typed classes. You could use a XDocument or XmlReader classes to parse and extract information from it.
If you're using .Net 4, the ExpandoObject might be what you need:
Represents an object whose members can be dynamically added and removed at run time.
You want to look into the factory pattern. The basic idea is:
for each XML node, get the type name / name of node
ask factory for type with given name
create object of the given type
pass the XML node to object to allow it to load its data
XSD schemas help here to verify the XML is structurally correct although not necessary. I did try this once, creating objects from XML, but I never found a way to have multiple schema files for one XML (this would have allowed me to extend the schema without changing the root schema, if you see what I mean).
If I am dealing with several standard xml formats what would be the best practice way of encapsulating them in C# 3.5? I'd like to end up with something similar to the System.ServiceModel.Syndication namespace.
A class that encapsulates the ADF 1.0 XML standard would be one example. It has the main XML root node, 6 child elements, 4 of which are required IIRC, several required and optional elements and attributes further down the tree. I'd like the class to create, at a minimum, the XML for all the required pieces all the way up to a full XML representation. (Make sense).
With LINQ 4 XML and extension classes, etc, etc, there has to be some ideas on quickly generating a class structure for use. Yes? No? :)
Am not sure if I gave enough details to get one correct answer but am willing to entertain ideas right now.
TIA
XML serialization seems a good approach. You could even use xsd.exe to generate the classes automatically...
EDIT
Note that the class names generated by the tool are usually not very convenient, so you might want to rename them. You might also want to change arrays of T to List<T>, so that you can easily add items where needed.
Assuming the class for the root element is named ADF, you can load an ADF document as follows :
ADF adf = null;
XmlSerializer xs = new XmlSerializer(typeof(ADF));
using (XmlReader reader = XmlReader.Create(fileName))
{
adf = (ADF)xs.Deserialize(reader);
}
And to save it :
ADF adf = ...; // create or modify your document
...
XmlSerializer xs = new XmlSerializer(typeof(ADF));
using (XmlWriter writer = XmlWriter.Create(fileName))
{
xs.Serialize(writer, adf);
}
Why not just follow the pattern of the SyndicationFeed object in the Syndication namespace? Create a class that takes in a Uri to the xml document or just takes in the document fragment.
Then parse the document based on your standards (this parsing can be done using LinqToXml if you wanted to, though regEx might be faster if you are comfortable with them). Throw exceptions or track errors appropriately when the document doesn't pass the specification rules.
If the document passes the parse step then break the pieces of the document out into public getter properties of your object. Then return the fully hydrated object back to the consumer for use
Seems pretty straight forward to me. Is that what you are after or are you looking for something more than this?