How to validate Xml in that specific way - c#

My problem is that i dont know how to properly write a xsd that allows me to validate xml in such way :
i need to have few necessary nodes (in any order) and to allow any other nodes to be in root
so for example i need to validate such xml, with 2 necessary nodes:
<root>
<necessary1/>
<someRandomNode1/>
<necessary2/>
<someRandomNode2/>
<someRandomNode3/>
</root>
but this has to be in any order and <xs:any/> is probably not what im looking for.
edit:
this 'someRandomNodeX' is not name of node, it can be everything. Number of this unscpecified nodes is unknown too.

There is a solution if the required elements and the non-required elements can be made in different namespaces. It requires XML Schema 1.1.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1"
xmlns:namespace="http://www.example.com/"
targetNamespace="http://www.example.com/">
<xs:element name="root">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element name="necessary1" type="xs:string"/>
<xs:element name="necessary2" type="xs:string"/>
<xs:any namespace="##other" processContents="lax"/>
<xs:any namespace="##local" processContents="lax"/>
</xs:choice>
<xs:assert test="exactly-one(namespace:necessary1) and exactly-one(namespace:necessary2)"/>
</xs:complexType>
</xs:element>
</xs:schema>
This validates:
<?xml version="1.0" encoding="UTF-8"?>
<namespace:root
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.com test.xsd"
xmlns:namespace="http://www.example.com/">
<namespace:necessary1/>
<someRandomNode1/>
<namespace:necessary2/>
<someRandomNode2/>
<someRandomNode3/>
</namespace:root>

Related

XSD includes a XSD and in turn includes another

Ok I don't know if the title is specific enough, but I'm having a problem here.
I have a XSD called
"A"
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:include schemaLocation="ATypeIn.xsd"/>
<xs:element name="A" type="ATypeIn"/>
</xs:schema>
As you can see it includes this next XSD
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:include schemaLocation="file:////C:/Users/aaaaa/Documents/GerarClasses/Types.xsd"/>
<xs:complexType name="ATypeIn">
<xs:sequence>
<xs:element name="Apol">
<xs:complexType>
<xs:sequence>
<xs:element name="R" type="RType"/>
<xs:element name="NAp" type="NApType"/>
<xs:element name="Ut"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
For the XSD.Exe to generate the class it needs the 3rd XSD called "Types" which is included in the 2nd.
Problem is in here, this XSD "Types" has a lot of types.
and the class generated when I call "xsd A.xsd /classes"
Includes all these extra things:
Am I doing something wrong or it's supposed to be like this and I can't do anything about it?
Thanks,
If I didn't explain myself good enough, please do ask about it and I will try to explain better.
PS: Obviously I changed the names in the code, so if there is any "mistake" it's for this reason.

How do I access and use (add/remove) elements for an custom app.config based on my own schema file?

I made my own schema xsd file and load it in my Project Solution like in the post here: How do I make an extension xsd for the web/app.config schema? . It worked like a charm, but now I can't figure it out at the next step how to access the elements and data in the app.config file.
My xds schema file code:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vs="http://schemas.microsoft.com/Visual-Studio-Intellisense" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="generalWorkDir" type="xs:string"/>
<xs:element name="workStations" type="wStation">
<xs:complexType name="wStation">
<xs:sequence>
<xs:element name="Name" type="xs:string">
<xs:element name="workDir" type="xs:string">
<xs:element name="ip" type="xs:string">
<xs:element name="port" type="xs:string">
</xs:sequence>
<xs:/complexType>
and the xml file app.config looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<generalWorkDir>c:/Temp/Default</generalWorkDir>
<workStations>
<wStation>
<Name>w1</Name>
<workDir>c:/Temp/w1</workDir>
<ip>127.0.0.1</ip>
<port>8080</port>
</wStation>
</workStations>
I mention I work on a Windows Forms application in C#.
Any suggestions? I want to write code in my application in order to access the data from app.config and to add or remove a new workStation.

Validating XML documents with XSD correctly

As a developer with a good deal of XML consuming and producing experience, I've never really interacted with schemas before. For the first time this is actually occurring for me.
I've run across a "feature" that I consider more of a bug which is well documented.
When using XDocument.Validate() it seems that there are cases in which the document will be valid if it doesn't match the schema specified. I feel this is most likely a flaw in my understanding of the relationship between XSDs, XML namespaces, and expected validation processes.
Therefore I submit to you my XML sample, my XSD sample, and my validation code.
XML - this is INTENTIONALLY the wrong document.
<?xml version="1.0" encoding="utf-8" ?>
<SuppliesDefinitions
xmlns="http://lavendersoftware.org/schemas/SteamGame/Data/Xml/Supplies.xsd">
<Supply type="Common">
<Information/>
<Ritual/>
<Weapon/>
<Tool count="1"/>
<Tool count="2"/>
<Tool count="3"/>
</Supply>
<Supply type="Uncommon">
<Information/>
<Weapon/>
<Tool count="1"/>
<Tool count="2"/>
<Tool count="3"/>
<Tool count="4"/>
</Supply>
<Supply type="Rare">
<Information/>
<Rune/>
<Weapon/>
<Tool count="2"/>
<Tool count="3"/>
<Tool count="4"/>
</Supply>
</SuppliesDefinitions>
The XSD used to validate it. (Again, this is intentionally the WRONG document for the above XML)
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="Encounters"
targetNamespace="http://lavendersoftware.org/schemas/SteamGame/Data/Xml/Encounters.xsd"
elementFormDefault="qualified"
xmlns="http://lavendersoftware.org/schemas/SteamGame/Data/Xml/Encounters.xsd"
xmlns:mstns="http://lavendersoftware.org/schemas/SteamGame/Data/Xml/Encounters.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:complexType name="ToolType">
<xs:attribute name="count" use="required" type="xs:int"/>
</xs:complexType>
<xs:complexType name="TaskType">
<xs:choice maxOccurs="unbounded" minOccurs="1">
<xs:element name="Weapon"/>
<xs:element name="Information"/>
<xs:element name="Tool" type="ToolType"/>
<xs:element name="Ritual"/>
</xs:choice>
</xs:complexType>
<xs:complexType name="EncounterType">
<xs:sequence maxOccurs="unbounded" minOccurs="1">
<xs:element name="Task" type="TaskType"/>
</xs:sequence>
<xs:attribute name="name" use="required" type="xs:string"/>
</xs:complexType>
<xs:element name="EncounterDefinitions">
<xs:complexType>
<xs:sequence maxOccurs="unbounded" minOccurs="1">
<xs:element name="Encounter" type="EncounterType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
And finally the validation code.
private static void ValidateDocument(XDocument doc)
{
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add(null, XmlReader.Create(new StreamReader(XmlSchemaProvider.GetSchemaStream("Encounters.xsd"))));
doc.Validate(schemas, (o, e) =>
{
//This is never hit!
Console.WriteLine("{0}", e.Message);
Assert.False(e.Severity == XmlSeverityType.Error);
});
}
I was wondering if someone can explain what I am doing wrong. I feel I'm making some incorrect assumptions about the way this SHOULD be working. It seems to me using one xsd against a completely unrelated XML document would be invalid.
There is no nodes in your XML that can be validated by the schema (namespaces are different). As result it does not report any errors. As far as I know behavior for nodes that are not matched to any schema is allow anything.
You also could set validation options in XmlReaderSettings to allow warnings:
ReportValidationWarnings - Indicates that events should be reported if a validation warning occurs. A warning is typically issued when there is no DTD or XML Schema to validate a particular element or attribute against. The ValidationEventHandler is used for notification.
Check out XmlSchemaSet.Add and HOW TO: Validate an XML Document by Using Multiple Schemas if you expect nodes from multiple namespaces to be present in the XML.

Displaying XML schema elements in treeview in order of appearance in XML

I need to display XSD files in a treeview. I already found one solution for this here!, but this just displays all the nodes in the file in the order they appear.
What I need is to display them in the order they appear in the XML file, and nested under the elements they will be nested under in the XML file:
<?xml version="1.0" encoding="IBM437"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="cat" type="xs:string"/>
<xs:element name="dog" type="xs:string"/>
<xs:element name="pets">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="cat"/>
<xs:element ref="dog"/>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
Would be displayed like this:
-Pets
-Dogs
-Cats
How do I undentify the root node? I think that once I got that I can recurse into each type in the root elemet to find its name.
I am looking at this XSD specifically!. Should I start from the element called 'Document'? It contains the 2 top level elements in this type of file - 'GrpHdr' and 'OrgnlGrpInfAndSts'.
Is this is a standard way to tackle something like this?
Apparently there isn't since an XSD may contain more then 1 root element.

How do I specify a list of required xml child elements that DONT need to be in sequence?

The following xml validates against the supplied xsd document. However when i start removing elements like from the xml it STILL validates!?
How do I write an xsd that forces the inclusion of elements?
<?xml version="1.0" encoding="UTF-8"?>
<Video>
<Title>
</Title>
<Description>
</Description>
<Contributor>
</Contributor>
<Subject>
</Subject>
</Video>
Then I have the xsd:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="UploadXSD"
targetNamespace="http://tempuri.org/UploadXSD.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/UploadXSD.xsd"
xmlns:mstns="http://tempuri.org/UploadXSD.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Video">
<xs:complexType>
<xs:sequence>
<xs:element name="Title" minOccurs="1" type="xs:string"></xs:element>
<xs:element name="Description" minOccurs="1" type="xs:string"></xs:element>
<xs:element name="Contributor" minOccurs="1" type="xs:string"></xs:element>
<xs:element name="Subject" minOccurs="1" type="xs:string"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
If you use xs:all as opposed to xs:sequence, the elements may appear in any order. There are some additional restrictions - for example, elements can not be specified multiple times using all (I'm not sure if you intend that usage, your schema would currently allow that.)
Your targetNamespace in the xsd should match the namespace of the xml you are trying to validate, i.e.
<Video xmlns="http://tempuri.org/UploadXSD.xsd">
<Title>
</Title>
<Description>
</Description>
<Contributor>
</Contributor>
<Subject>
</Subject>
</Video>

Categories