<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="abc" targetNamespace="http://schemas.businessNameHere.com/SoftwareNameHere"
elementFormDefault="qualified"
xmlns="http://schemas.businessNameHere.com/SoftwareNameHere"
xmlns:mstns="http://schemas.businessNameHere.com/SoftwareNameHere"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="..." type="..." />
<xs:complexType name="...">
I am working on a project using XSD to generate .cs file. My question is concerning the string "http://schemas.businessNameHere.com/SoftwareNameHere" If I change it, it doesn't work. But the http:// is not a valid one... what is the logic behind and where can I can information about what to put there or how to change it?
XSD namespaces do not have to be valid URI's. Having a namespace string that is a URL doesn't mean anything is fetched from the URL, or anything to do with the web at all - it's simply a string like any other. So although the URL may be invalid from the sense that it doesn't actually point to anything, it's still a valid string as a namespace declaration.
You can read up on some of the reasoning behind namespace identifiers being in this format here.
There are several reasons for using URL's as a namespace identifier, but mainly it is for convenience - it's a unique identifier that generally has some meaning attached to it for the users, much like the way Java namespaces classically begin with "com", "org" or "net".
For the nitty gritty of why namespaces are in URI (technically, IRI) format, you can read the W3C's standards for XML namespaces. The specify that XML Namespaces are in IRI (International Resource Identifier) format, defined in RFC3986.
For more information on how to properly use namespaces, there are lots of great walkthroughs, like this one. What isn't working when you change the namespace?
The namespace does not have semantic meaning beyond having to be unique. People normally use a URI form as that may point to documentation, but this is not a requirement.
In this case, it is the default namespace and it is possible that the application that you are using to generate your .cs files is hardcoded to use it.
In a well written application, nothing should break if you simply change a namespace string.
xmlns="http://schemas.businessNameHere.com/SoftwareNameHere"
This is not a valid URL where some document has to exist - it's only a string that represents a XML namespace (like a namespace in your C# application called System.Data or whatever).
You can easily change that string - there's nothing being referenced here. (but that's a common misconception)
People often use the URL-syntax because the domain registered to you / your company is guaranteed to be unique worldwide -> thus the XML namespace you derive from it will also be unique worldwide.
Related
What does xmlns:dc mean in C# WPF XAML code? Can't find anything on it. Is it directory context? Domain controller?
Sorry for missing context.
I know xmlns is just xaml name space, but i want to know what dc stands for, like what does it mean?
xmlns:dc="clr-namespace:SomethingHere;assembly=SomethingHere"
"dc" is an arbitrary prefix - it is used to reference the namespace as a short hand way, but can be anything you like.
Here's the explanation by the guy who thought it up:
http://www.xml.com/pub/a/1999/01/namespaces.html
dc would just be the namespace of a control you're trying to use, so if you wanted to use a control called ThisControl that was inside the assembly "clr-namespace:SomethingHere;assembly=SomethingHere" you would need to use dc:ThisControl in the xaml.
Working with Cytoscape I have found that xmlns:dc refers to XLM Namespace(xlmns) and the Dublin Core(dc) metadata standard:
https://www.dublincore.org/specifications/dublin-core/dcmi-terms/
When exporting xgmml from cytoscape, part of the xml refers to http://purl.org/dc/elements/1.1/ which redirects to the url above.
Example:
<graph id="78" label="TAPBPL" directed="1" cy:documentVersion="3.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cy="http://www.cytoscape.org" xmlns="http://www.cs.rpi.edu/XGMML">
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 know this is pretty silly but just wondered if anyone had a link or knows exactly what this code is doing on my page?
namespace com.gvinet.EblAdapter.ebl
{
[Serializable]
[DesignerCategory("code")]
[GeneratedCode("System.Xml", "4.0.30319.225")]
[DebuggerStepThrough]
[XmlType(Namespace = "http://addresshere")]
public class TSAPassenger
{
then here is all of the strings for the form like name, address and such
I am thinking it is trying to grab the XML file that was created from the Database but just want to make sure.
It is not. These are all just metadata attributes.
Serializeable - Use the standard XmlSerializer to take public properties and fields and convert to XML for transport using no customization to the format (like ISerializable would). It is usually only used when going out of process (remoting, Web Services, WCF, etc)
DesignerCategory - This can be used a number of ways. This one tends to be used by the property grid in visual studio as a way to organize sections.
GeneratedCode - The application generated it for you, utilizing the System.Xml namespace in version 4.0.
DebuggerStepThrough - If you are stepping through code (F11), by default, skip over anything here (don't step into a property getting for example).
XmlType - Part of the serializer that allows you to provide a specific namespace that is generated in the output.
The items here do not actually get anything, just describe certain aspects of how something may be loaded/handled.
Hope that makes sense.
The Serializable and XmlType attributes are instructing the XML serializer that the class can be serialized and the schema to use when doing so.
XmlType Attribute
Serializable Attribute
DesignerCategory("code") Attribute
DebuggerStepThrough Attribute
These are attributes - used for declarative programming - you can find more about declarative programming online. But here is the link to .net attribute hierarchy page to get you started: http://msdn.microsoft.com/en-us/library/aa311259(VS.71).aspx
Also, these pages may be helpful:
What are attributes: What are attributes in .NET?
Attributes in C#: http://www.codeproject.com/Articles/2933/Attributes-in-C
The background
I'm developing a REST API for a C#.NET web application using WCF. I configured it to use the XmlSerializer rather than its default DataContractSerializer, for greater control over the XML format. I created a generic ResponseContract<TResponse, TErrorCode> data contract, which wraps the response with <Api> and <Response> for generic data like request status, error messages, and namespaces. An example method:
ResponseContract<ItemListContract, ItemListErrorCode> GetItemList(...)
An example response from the above method:
<?xml version="1.0" encoding="utf-8"?>
<Api xmlns="http://example.com/api/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Response Status="OKAY" ErrorCode="OKAY" ErrorText="">
<Data Template="ItemList">
<Pages Template="Pagination" Size="10" Index="1" Count="13" Items="126" />
<Items>
<Item example="..." />
<Item example="..." />
<Item example="..." />
</Items>
</Data>
</Response>
</Api>
The problem
This works very well for services whose methods all have the same generic ResponseContract types. WCF or XmlSerializer expects each contract to have a unique name within its namespace, but the service is now returning a generic contract with different types having the same XML root name:
ResponseContract<ItemListContract, ItemListErrorCode> GetItemList(...)
ResponseContract<ItemContract, ItemErrorCode> GetItem(...)
With the resulting exception:
The top XML element 'Api' from namespace 'http://example.com/api/' references distinct types Company.Product.ApiServer.Contracts.ResponseContract`2[Company.Product.ApiServer.Contracts.Items.ItemListContract,Company.Product.ApiServer.Interfaces.Items.ItemListErrorCode] and Company.Product.ApiServer.Contracts.ResponseContract`2[Company.Product.ApiServer.Contracts.Items.ItemContract,Company.Product.ApiServer.Items.ItemErrorCode]. Use XML attributes to specify another XML name or namespace for the element or types.
The service must allow different return types. This is difficult to achieve because the ResponseContract<TResponse, TErrorCode> (which sets the name & namespace) is generic and returned by all API methods. I also need to maintain WSDL metadata integrity, which means no dynamic changes using reflection.
Attempted solutions
Changing the XML attributes declaratively is not possible, since the <Api> root element and its attributes are completely generic (in ResponseContract).
Changing the attribute namespace at runtime using reflection (eg, 'http://example.com/api/Items/GetItemList') has no effect. It's possible to get attributes, but changes to them have no effect. This would break WSDL anyway.
When implementing IXmlSerializable, the writer is already positioned after the <Api> start tag when WriteXml() is invoked. It's only possible to override the serialization of <Api>'s child nodes, which cause no problem anyway. This wouldn't work anyway, since the exception is thrown before the IXmlSerializable methods are called.
Concatenating the constant namespace with typeof() or similar to make it unique doesn't work, because the namespace must be a constant.
The default DataContractSerializer can insert type names into the name (like <ApiOfIdeaList>), but DataContractSerializer's output is bloated and unreadable and lacks attributes, which is not feasible for the external reusers.
Extending XmlRootAttribute to generate the namespace differently. Unfortunately there is no type information available when it's invoked, only the generic ResponseContract data. It's possible to generate a random namespace to circumvent the problem, but dynamically changing the schema breaks the WSDL metadata.
Making ResponseContract a base class instead of a wrapper contract should work, but would result in a lot of duplicated generic data. For example, <Pages> and <Item> in the example above are also contracts, which would have their own equivalent <Api> and <Response> elements.
Conclusion
Any ideas?
I got the tumbleweed badge for this one!
I abandoned the described approach because I couldn't find a viable solution. Instead, every contract inherits a nullable QueryStatus<TErrorCode> property from the generic BaseContract<TContract, TErrorCode>. This property is populated automatically for the main contract, and null for subcontracts.
The Xml response I receive is as follows:
<response>
<item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="java:com.someDomain.item">
<name>some name</disc-name>
<description>some description</disc-desc>
</item>
<item xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="java:com.someDomain.item">
<name>some name</disc-name>
<description>some description</disc-desc>
</item>
<otherValue>12.1</otherValue>
</response>
My class is decorated as such:
[XmlElement("item")]
public Item[] Items{get;set;}
[XmlElement("otherValue")
public string OtherValue{get;set;}
When I attempt to deserialize the above Xml to the class described, I receive an error of "Namespace prefix 'java' is not defined". Adding the "namespace" attribute to the class resolves the parsing error(however, the xml is then distorted from the original).
ie
[XmlElement(ElementName="item",Namespace="java")]
How should I be decorating a given property to match up with a new namespace? Or, how do I correctly define the namespace?
I'm not 100% on using a stock array for my enumerable section either, but I think the namespace issue takes precident at the moment. Any insight or thoughts are greatly appreciated!
UPDATE:
I think the question is better rephrased now that I've gone back and forth a bit:
How do you use an XmlElementAttribute(or other attribute) to have a class that can serialize into the item snippet above, including the xsi tags?
As for my particular problem, I've realized since the Xml response is out of my control, I don't need the xsi attributes to begin with. To workaround the serialization issue, I'm simply doing the following(XmlElement element contains the original document above):
foreach(XmlNode node in element)
node.Attributes.RemoveAll();
I'm only noting my personal workaround as this is not actually a solution.
You were right the first time. "java" is not a namespace. It's a namespace prefix. That's an abbreviation of the namespace, for use in the XML. Otherwise, the actual namespace would need to be repeated wherever you currently see "java:".
You can use List<Item> instead of Item[].
Unfortunately this is valid XML, and completely conforms to the XML Standard.
It validates, it's correct and it's complete.
The problem you're having is in the deserialization, which is not a part of the XML Standard and is related to how .NET maps declared XML types to internal CLR types.
The xsi:type is a namespace reference and is intended to allow XML documents to substitute a derived type from another namespace for the declared type in the schema.
I know from my own experience that coders tend to react in shock that this sort of thing is even legal, much less correct XML. It basically hijacks your schema.
You do not need even need to include the foreign namespace in order for this to be considered correct.
(see this article for more ranting on this subject: http://norman.walsh.name/2004/01/29/trainwreck)
Now, as to how to handle your stated problem: deserialize this mess.
1) process the xml text and remove the xsi-types declaration and hope there are no fields declared that extend the base type.
2) declare a type that derives from your base type in the schema.
This looks like the following:
// note this "XmlIncludeAttribute" references the derived type.
// note that in .NET they are in the same namespace, but in XML they are in different namespaces.
[System.Xml.Serialization.XmlIncludeAttribute(typeof(DerivedType))]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://BaseNameSpace")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://BaseNameSpace", IsNullable=true)]
public partial class MyBaseType : object
{
...
}
/// <remarks/>
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://DerivedNameSpace")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://DerivedNameSpace", IsNullable=true)]
public partial class DerivedType: MyBaseType
{
...
}
This is only a rough outline, hopefully enough to get you started. Note that this is not an easy problem to solve progmatically because it's always possible for someone to feed you XML and it will validate but not deserialize properly.