How do you generate xsd namespace prefixes in the resulting output file? - c#

I've gone over multiple topics and solutions that talk specifically about this issue. None have worked or I fail to understand what I am doing wrong.
I would like for the namespace prefixes to accompany the element names in the resulting xml output file.
I'm am using the XSD command with Visual Studio 2008 from the VS Command Prompt
Here's my xsd schema for Trial.xsd
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="Junk"
targetNamespace="http://www.opengis.net/kml/2.2"
xmlns="http://www.opengis.net/kml/2.2"
xmlns:gx="http://www.google.com/kml/ext/2.2"
xmlns:kml="http://www.opengis.net/kml/2.2"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:import namespace="http://www.google.com/kml/ext/2.2" schemaLocation="TestSchema.xsd" />
<!-- Start LookType -->
<xs:complexType name="LookType">
<xs:sequence>
<xs:element ref="gx:TimeSpan" minOccurs="0" />
<xs:element name="longitude" type="xs:string" />
</xs:sequence>
</xs:complexType>
<!-- End LookType -->
<xs:element name="Te" type="LookType" />
</xs:schema>
Here's my xsd schema for TestSchema.xsd
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="TestSchema"
targetNamespace="http://www.google.com/kml/ext/2.2"
xmlns="http://www.google.com/kml/ext/2.2"
xmlns:gx="http://www.google.com/kml/ext/2.2"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:element name="TimeSpan" type="gx:GXTimeSpanType" />
<!-- Start GXTimeSpanType -->
<xs:complexType name="GXTimeSpanType">
<xs:sequence>
<xs:element name="begin" type="xs:string" />
<xs:element name="end" type="xs:string" />
</xs:sequence>
</xs:complexType>
<!-- End GXTimeSpanType -->
</xs:schema>
I´m generating the resulting class file Trial.cs by using xsd TestSchema.xsd ./Trial.xsd /c /l:cs /n:T
In a program I assign these junk values and write them to file using XmlDocument, XmlSerializer and FileStream
T.LookType te = new T.LookType();
te.longitude = "34.444";
te.TimeSpan = new T.GXTimeSpanType();
te.TimeSpan.begin = "2010-02-26T20:22:00Z";
te.TimeSpan.end = "2010-02-26T20:23:42Z";
I've excluded the method that saves out the file using XmlDocument, XmlSerializer and FileStream as it is a little thicker then I'd like to post unless that is part of the problem.
This is what I get in the resulting file
<?xml version="1.0" encoding="utf-16"?>
<Te xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.opengis.net/kml/2.2">
<TimeSpan xmlns="http://www.google.com/kml/ext/2.2">
<begin>2010-02-26T20:22:00Z</begin>
<end>2010-02-26T20:23:42Z</end>
</TimeSpan>
<longitude>34.444</longitude>
</Te>
This is what I want in the resulting file. Notice the gx:TimeSpan element and the xmlns:gx namespace definition being added to the main Te element.
<?xml version="1.0" encoding="utf-16"?>
<Te xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.opengis.net/kml/2.2"
xmlns:gx="http://www.google.com/kml/ext/2.2">
<gx:TimeSpan>
<begin>2010-02-26T20:22:00Z</begin>
<end>2010-02-26T20:23:42Z</end>
</gx:TimeSpan>
<longitude>34.444</longitude>
</Te>

It doesn't matter on which element the prefixes are declared on, as long as they're declared before they are used. Any code that doesn't like this is broken.
Perhaps because it doesn't matter, XML Schema has no way to influence on which element the prefixes are declared, or which prefix is used.

Related

Xsd import doesn't work

I'm trying to use an xsd defined in http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd#. I saved that definition as one xsd file to my disk and change the import in a different xsd to use it but the visual studio doesn't detected or give me any clue by intellsense. i also set the visual studio menu option xml >menu > schemas and select the file, but doesn't work.
My xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
targetNamespace="http://x/y/z/w/"
xmlns="http://x/y/z/w/"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<!--<xs:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd#"/>-->
<xs:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="file:/B:/Test.xsd" id="ds"></xs:import>
<xs:element name="elementX">
<xs:complexType>
<xs:sequence>
<xs:element ref="ds:Signature"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
The import i want to use is allocated in http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd#
my question: is there any way to change the definition in order to appears in the intellsense.
Thanks in advance

How to generate xsd from xml in code behind

What I want to do is generating xsd file from xml which will be passed as string.
Sample:
Let's say we have that kind of xml passed in string:
<?xml version="1.0" encoding="utf-8"?>
<Sample>
<SampleId>41111111124</AnimalId>
<SampleName>string</SampleKind>
</Sample>
I would like to generate from this above xsd file from code behind:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Sample">
<xs:complexType>
<xs:sequence>
<xs:element name="SampleId" type="xs:unsignedLong" />
<xs:element name="SampleName" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
On msdn couldn't find such thing.
Is it even possible to make it in c# code behind?
Ok I found solution for this:
XmlSchemaInference is what I needed.

Exception when loading partial xml data into xsd dataset

I have the following .xsd code:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" id="MyDataSet">
<xs:element name="Row">
<xs:complexType>
<xs:sequence>
<xs:element name="Number" type="xs:int"/>
<xs:element name="Item" type="xs:string"/>
<xs:element name="Comment" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
And the following .xml file:
<?xml version="1.0" standalone="yes"?>
<MyDataSet>
<Row>
<Number>1</Number>
<Item>first</Item>
</Row>
</MyDataSet>
Since the "Comment" tag is missing in the xml file, I get an exception when running:
MyDataSet myDataSet = new MyDataSet();
myDataSet.ReadXml(xmlFilePath);
The exception is: "Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints."
How can I define the .xsd to be able to receive partial xml data and fill null or any default value when a tag is missing?
Got it... I needed to add the attribute "Nillable" with the value of "true" to the fields that may not arrive in the xml.

c# read DataSet Child tables

<products>
<product id="1">
<photos>
<photo addr="1.jpg" />
</photos>
<parameters>
<parameter name="name" />
</parameters>
</product>
</products>
Hello, I have this xml, I want to get values, like photo addr or parameter name I can't.
in DataGrid I am getting like new table. How to Read this parameters by product id?
foreach (DataTable t in dataSet.Tables)
{
Console.WriteLine(t);
}
I am getting: product, photos, photo, parameters, parameter.
Sorry for my English
OK, you need to use schema inferencing to generate an XSD file, then run xsd.exe to generate the DataSet that you're looking for.
To begin with, the XML you've provided won't work off the bat, because you don't have a root node. I'm taking a wild guess here, but if <products> is the root node, we could reformat your XML to look like this:
<products>
<product id="1">
<photos>
<photo addr="1.jpg" />
</photos>
<parameters>
<parameter name="name1" />
</parameters>
</product>
<product id="2">
<photos>
<photo addr="2.jpg" />
</photos>
<parameters>
<parameter name="name2" />
</parameters>
</product>
</products>
We could then take this XML and infer the XSD from it via the XmlSchemaInference class. When I inferred the schema from the XML above, I got this:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="products">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="product">
<xs:complexType>
<xs:sequence>
<xs:element name="photos">
<xs:complexType>
<xs:sequence>
<xs:element name="photo">
<xs:complexType>
<xs:attribute name="addr" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="parameters">
<xs:complexType>
<xs:sequence>
<xs:element name="parameter">
<xs:complexType>
<xs:attribute name="name" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedByte" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
I then ran xsd.exe with the /dataset option, which gave me a fully functional DataSet representing the original XML. Populating the dataset and the using the DataSet.GetXml() returns the expected XML result.
Final note: I'm not advocating the use of DataSets over domain objects, etc etc. I just wanted to show you what would be the steps for accomplishing your stated objective.
By default DataSet assumes a schema based on elements, not attributes. You'd need to build an xsd for your data to get DataSet to read that XML correctly.
Due to the way this XML is constructed there's no easy way to read this into a DataSet directly. You'd have to use xsd.exe to generate an xsd file and then hand edit it with appropriate attributes from the msdata namespace. It's a quite painful process.
You coud transform the document to a form which would probably parse correctly into DataSet either by rewriting the XML using LINQ or applying an XslCompiledTransform:
<products>
<product id="1">
<photo addr="1.jpg" />
<parameter name="name" />
</product>
</products>
You could also consider using LINQ to XML on it instead of trying to use a DataSet:
var productsInfo = from product in productsElement.Descendants("product")
from photo in product.Descendants("photo")
from parameter in product.Descendants("parameter")
let id = product.Attribute("id")
let addr = photo.Attribute("addr")
let name = parameter.Attribute("name")
select new { ID = id.Value, Addr = addr.Value, Name = name.Value};
If you're developing a new XML layout rather than working with an existing one, you can create the DataSet first using the designer. Populate it with some dummy data, then you can use WriteXml to get the xsd schema and sample data. To preserve relationshps in the XML ouput be sure to set the Nested property on your Relations to be true (See Nesting DataRelations (ADO.NET)).

Can any one tell where i went wrong in validating an XML with XSD in C#

Hi all i have my XML file as follows
Name of XML XMLFile2.xml
<?xml version="1.0"?>
<Product ProductID="123"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="Product.xsd">
<ProductName>XYZ</ProductName>
</Product>
My XSD is as follows
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="Product"
targetNamespace="http://tempuri.org/Product.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/Product.xsd"
xmlns:mstns="http://tempuri.org/Product.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Product">
<xs:complexType>
<xs:sequence>
<xs:element name="ProductName" type="xs:string"></xs:element>
</xs:sequence>
<xs:attribute name="ProductID" type="xs:int" use="required"/>
</xs:complexType>
</xs:element>
This is my code
string strPath = Server.MapPath("XMLFile2.xml");
XmlTextReader r = new XmlTextReader(strPath);
XmlValidatingReader v = new XmlValidatingReader(r);
v.ValidationType = ValidationType.Schema;
v.ValidationEventHandler +=
new ValidationEventHandler(MyValidationEventHandler);
while (v.Read())
{
}
v.Close();
if (isValid)
Response.Write("Document is valid");
else
Response.Write("Document is invalid");
I am getting the following errors
Validation event
The targetNamespace parameter '' should be the same value as the targetNamespace 'http://tempuri.org/Product.xsd' of the schema.Validation event
The 'Product' element is not declared.Validation event
Could not find schema information for the attribute 'ProductID'.Validation event
The 'ProductName' element is not declared.Document is invalid
Can any one tell where i went wrong.
Your XSD is set to validate the "http://tempuri.org/Product.xsd" namespace, but your XML contains only elements from the "" namespace.
You need to either (a) change the XML file to use the "http://tempuri.org/Product.xsd" namespace, or (b) change the XSD file to use the "" namespace, depending on your user requirements.

Categories

Resources