Generate C# class from XSD (xhtml.blkstruct.class) - c#

I have an xsd file, simplified as below with an element referencing the xhtml.BlkStruct.class. I have tried xsd.exe and xsd2code trying to generate a C# class from it, but I am always getting errors.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3.org/1999/xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:xhtml="http://www.w3.org/1999/xhtml">
<xs:complexType name="test">
<xs:group ref="xhtml.BlkStruct.class"/>
</xs:complexType>
</xs:schema>
This is the error (reference to an undeclared / not declared model group)
Error: Verweis auf eine nicht deklarierte Modellgruppe 'http://www.w3.org/1999/xhtml:xhtml.BlkStruct.class'.
Can anybody help me out what is going wrong here?
Background I am tryint to XmlSerialize a string containing (simple) HTML/XML mixed with sting content, so things like
&ltp&gt, &ltdiv&gt, etc
for example
Hello &ltu&gtunderlined text&lt/u&gt &ltb&gtbold text&lt/b&gt world

Well, you're not supplying the xhtml.BlkStruct.class anywhere in your XSD. You might need to include its definition to succeed in the code generation. Download the file from http://www.w3.org/MarkUp/SCHEMA/ and add a
<xs:include schemaLocation="xhtml-basic11-model-1.xsd">
But do you really need a strongly typed DOM? A simpler solution is to define your test field as string, and include your HTML as CDATA or encoded html. My experience is that mixing XML with HTML is always a bad design choice and you have better luck with treating the HTML part as text.

Related

XML validating with XSD failing due to 'refname' not declared despite refname not allowed for schemas

I am trying to validate an XML via an XSD in c# code. However it keeps throwing an XmlSchemaValidationException, namely "The 'refname' attribute is not declared.".
The code doing the validation:
XmlReaderSettings xmlSettings = new XmlReaderSettings();
xmlSettings.Schemas = new System.Xml.Schema.XmlSchemaSet();
xmlSettings.Schemas.Add(null, #"\\[Network-drive path]\KVSchemaMod.xsd");
xmlSettings.ValidationType = ValidationType.Schema;
xmlSettings.DtdProcessing = DtdProcessing.Parse;
xmlSettings.ValidationFlags = XmlSchemaValidationFlags.AllowXmlAttributes;
xmlSettings.ValidationFlags = XmlSchemaValidationFlags.ProcessInlineSchema;
xmlSettings.ValidationFlags = XmlSchemaValidationFlags.ReportValidationWarnings;
XmlReader reader = XmlReader.Create(#"\\[Network-drive path]\KV_Article.xml", xmlSettings);
// Parse the file.
while (reader.Read()) ;
The XSD (with repetitous parts removed):
<?xml version="1.0" encoding="iso-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:sql="urn:schemas-microsoft-com:mapping-schema">
<xs:annotation>
<xs:appinfo>
<sql:relationship name="ProductIdentifier"
parent="tblKVProduct"
parent-key="record_reference"
child="tblKVProductIdentifier"
child-key="record_reference" />
... (More SQL-mappings)
<xs:element name="ONIXMessage" sql:is-constant="1">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="Product" sql:relation="tblKVProduct">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="RecordReference" sql:field="record_reference" >
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="0"/>
<xs:maxLength value="32"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
...(More elements under Product)
The XML to be validated (ONIX-standard):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ONIXMessage SYSTEM "http://www.editeur.org/onix/2.1/reference/onix- international.dtd">
<ONIXMessage>
<Product>
<RecordReference>0786606274</RecordReference>
<NotificationType>03</NotificationType>
<ProductIdentifier>
<ProductIDType>01</ProductIDType>
<IDTypeName>Kustantajan tuotenumero</IDTypeName>
<IDValue>95535</IDValue></ProductIdentifier>
<ProductIdentifier>
<ProductIDType>02</ProductIDType>
<IDValue>0786606274</IDValue></ProductIdentifier>
<ProductIdentifier>
<ProductIDType>03</ProductIDType>
<IDValue>9780786606276</IDValue>
</ProductIdentifier>
...(And more Product-fields)
The XML also has a Header tag as the first child of ONIXMessage (followed by all Product tags that as also childrens of ONIXMessage), but since none of the fields there are referenced in the schema I don't see how they could cause this particular error.
As I googled the error I read up on the XmlSchemaElement.RefName property (MSDN Definition) it even explicitly says that "The value cannot be set if the containing element is the schema element."
Since that is the case for the XSD I don't understand why it throws an error about it not being declared.
I've been trying to find out if this could be related to the lack of namespace, but in my mind that shouldn't be a problem since there is none in neither the XML nor the XSD. Or does one need to force a namespace onto the root-element in order to validate the XML?
The validating code does work with another set of XML/XSD (very different build-up on those though), could that just be a fluke though and the error actually in the way I validate?
Just for completion's sake, the Header tag in the XML:
<Header>
<FromCompany></FromCompany>
<FromPerson></FromPerson>
<FromEmail></FromEmail>
<AddresseeIdentifier>
<AddresseeIDType></AddresseeIDType>
<IDTypeName></IDTypeName>
<IDValue></IDValue>
</AddresseeIdentifier>
<ToCompany></ToCompany>
<ToPerson></ToPerson>
<MessageNumber></MessageNumber>
<SentDate></SentDate>
<MessageNote></MessageNote>
</Header>
It's not possible to reproduce your problem, given that you haven't provided a complete example. If you want answers based on anything other than speculation, you need to cut down your schema and your data to the smallest example that illustrates the problem, so question answerers can reproduce the problem and study it in more detail. It will often happen, of course, that your problem dissolves in the process because you come to see what's going wrong in the process of finding a small example of the problem. But that's just a risk you have to take.
That said, however, I'll go ahead and speculate. The RefName property on the XMLSchemaElement object is almost certainly a red herring. The message makes it sound much more as if the XML you are attempting to validate has an attribute named refname somewhere (in the bit you elided), and your XSD schema has no definition for it. Certainly the XSD fragment you provide has no definition for it.
The vocabulary defined at http://www.editeur.org/onix/2.1/reference/onix-international.dtd (which you point to in your XML), however, does define refname as an attribute on many elements (probably all of them, though I haven't checked each one individually). So it's not at all implausible that an ONIXMessage element might contain a descendant with a refname attribute.
Actually, it's not just not implausible; it's certain.
The DTD pointed to by your XML supplies a default value for the refname attribute on all elements (at least, all the ones I've seen), for which your XSD schema declaration appears not to be prepared. That is, the first start-tag of your document seen by the schema validator is not <ONIXMessage> but <ONIXMessage refname="ONIXMessage" shortname="ONIXmessage">.
If you're not using the XSD available from www.editeur.org, the simplest way forward is probably to reconsider that decision and use the schema from editeur.org instead of rolling your own. It includes declarations for the refname and shortname attributes. If you are using that schema, or rather trying to use it, something has gone badly wrong and your validator is not finding or reading it. In that case, your best way forward is to figure out why your system is not finding the correct schema documents.

How does XML Schema declarations work and refer to each other?

There is something fundemental I don't understand about Xml Schema declarations. I have the following declaration in an .xsd file:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="tile">
<xs:restriction base="xs:string">
<xs:pattern value="[a-z][0-9]"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="move">
<xs:complexType>
<xs:sequence>
<xs:element name="T" type="tile" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
So, for example <move><T>a0</T><T>v5</T></move> should be a valid XML element according to the xsd file. (I've simplified the actual declaration, so the move may not make sense)
Background: I am developing a project in C# 4.0. I use this xsd file as a project source. When I receive an XElement from somewhere, I first check whether it is valid according to the xsd above. The C# code works OK.
Here is my question (hopefully a single question, asked three times):
1) I want to put my declarations on a domain. Let's say aliferhat.com. Or do I want to? Why should I want to do that? How can I do that? How can I use that declaration later from somewhere else?
2) I will have many similar xsd files. Most of them will use the "tile" definition, so I want to put the part "tile" on a seperate file, and refer to that file from other xsd files. How can I do that? How will the system know where to look for definitions?
3) This is what the visual studio generates when I add a new XSD file to the project:
<xs:schema id="temp"
targetNamespace="http://tempuri.org/temp.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/temp.xsd"
xmlns:mstns="http://tempuri.org/temp.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
</xs:schema>
What does xmlns:xs and targetNamespace attributes do? Are xs:element and the rest really defined in one of these URIs? Do the C# compiler really look up those URIs for the definitions?
I hope and guess I have asked only one question. I've read the "XML schema definition" page on W3 schools but could not find the answer. Any help will be appreciated.

.NET XmlSerializer and decimals

I used xsd.exe on a remote xsd file to generate some C# class definitions. One type is defined as
<xs:element name="amount">
<xs:simpleType>
<xs:restriction base="xs:decimal">
<xs:fractionDigits value="2"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
When I try to deserialize an xml file I get the error:
There is an error in XML document (30, 12). ---> System.FormatException: Input string was not in a correct format.
This only seems to happen when there's a comma used as a grouping separator (i.e 87,000). If I go through and delete the commas wherever there's an error deserialization works fine.
Is there some modification I can make o the xsd to allow for comma grouping? Or better yet a way to allow for it in my code? Trying to parse a decimal in my code with commas works fine, it's just not liking it in the xml file.
"87,000" does not match the xs:decimal type.
There is no XSD type that permits commas.
The definition of this datatype defines no restrictions whatsoever on the size of numbers permissible under this datatype. Unless your form processing is prepared to deal with a number thousands of digits long (or even longer), you should use a restriction on the allowed upper and lower limits, and number of digits past the decimal point.

c# XSLT transform doesnt work if the XML file has a schema attached?

We have an odd problem, we are tranforming a pretty complicated XML file using several XSLT files, this isnt the issue.
The issue is that IF the XML file is attached to the schema, the transform doesnt work, if we remove the schema declaration it begins to work ok.
Any clues what the problem would be?
Here is the schema declation
<xs:schema id="play"
targetNamespace="highway"
elementFormDefault="qualified"
xmlns="highway"
xmlns:mstns="highway"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
And we are simply using the following code to link it (Visual Studio Intellisense then kicks in)
<helloElement name="hello" xmlns="highway">
I appreciate this isnt much to go on, not sure what to offer in terms of symptoms, let me know if you need any info.
Many thanks!
The problem is not the schema, the problem is the namespace declaration xmlns="highway" which your stylesheet(s) need to take into account with e.g.
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:hw="highway"
version="1.0">
<xsl:template match="hw:helloElement">
...
</xsl:template>
</xsl:stylesheet>
and so on, anywhere you match or select an element you need to use a prefix.
When you add the schema declaration, you are adding a default namespace to your XML document (xmlns="highway") which wasn't there before. This will then affect the interpretation of element references and XPATHs in the XSLT, because all your elements are now no longer <someElement>, they are <highway:someElement>. Check out this link for more information.

Creating an XSD schema

I have an xml tag:
<ROW field1="value 1" field2="value 2" ... />
fieldi has a string value, and number of attributes fieldi is variable, but not less than 1. Is it possible to create an xsd schema for this tag?
possible xml document
<ROWDATA>
<ROW field1="dfgdf" field2="ddfg"></ROW>
<ROW field1="dfedf" field2="djkfg" field3="cdffd"></ROW>
<ROW field1="dfedf" field2="djkfg" field3="cdffd" field4="dfedf" field5="djkfg" field6="cdffd"></ROW>
</ROWDATA>
in this xml document, which I receive from a web server, can be a variable number of attributes field (I noted them as fieldi, where i means the order of a specific attribute field)
So I have, unknown number of ROW elements and unknown number of field attributes in the ROW element
Thanks
If you're using Visual Studio 2008:
Open your Xml file in Visual Studio
Go to the 'Xml' menu option at the top of the screen
Choose 'Create Schema'
This will generate your xsd schema(s)
EDIT
Try this example for details on setting minOccurs (on elements) or required (on attributes) so you can manipulate your derived schema.
If you are not comfortable in writing XSD yourself, use some generator like this.
EDIT: Based on your XML in comments, I can think of below structure of XSD
<xsd:element name="FieldHeader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Fields" type="xsd:string"/> <!--use minOccurs maxOccurs here-->
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:simpleType name="fieldi">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="Fields">
<xsd:list itemType="fieldi" />
</xsd:simpleType>
I think I have understood your requirement. Just to avoid misconceptions, let me reveal what I have understood once:
"You have an xml file which contains an element with the name fieldi, comes with set of some unknown attributes. Which means you don't know [or say don't want] the names and values of those attributes. Just want to see, there is at-least 1 attribute appearing",
Well. sorry to say that, this requirement is running out of capability of XML-schema. :-[
You cannot have attributes undeclared in schema. If it appears in xml, it requires to have a proper definition for that. There is something called <anyAttribute/> [click-here] which again requires definition [somewhere, in another linked schema].
1) Defining all the possible attributes making use="optional", doesn't look practically possible. And also your last requirement go skipped.
2) If it is possible then, convert all the attributes to elements [using transformation, or you can either ask the sender to do so, I don't know how complicate it is in your case], And define element <any/>, which sounds somewhat comfortable. but your requirement [at-least one attribute must appear] is still not achieved.
so this is it I can add-up for you. If you can change the requirement or input xml structure then let me know, I will see, whether I can help you in any-other ways ..
regards,
infant-pro
I solved the problem but in other way, by controlling the deserialization of the xml document in the way I need. However, I don't like this solution, because I had wanted to create classes from the xsd scheme and use them in my code.
Anyway, thanks to everybody

Categories