开发者

How to validate, on runtime, xml against xsd without save the xsd file on local folder?

开发者 https://www.devze.com 2023-01-04 17:29 出处:网络
My objective is to validade a xml file against the xsd whitch is in a string variable. Ps.: I already wrote a question numbered 3072697 on Friday. But I couldn\'t add this code today.

My objective is to validade a xml file against the xsd whitch is in a string variable. Ps.: I already wrote a question numbered 3072697 on Friday. But I couldn't add this code today.

book.xml:

<?xml version="1.0" encoding="utf-8"?>
<author  xmlns='urn:bookstore-schema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
  <first-name>Herman</first-name>
  <last-name>Melville</last-name>
</author>

book.xsd:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="NewDataSet" targetNamespace="urn:bookstore-schema" xmlns:mstns="urn:bookstore-schema" xmlns="urn:bookstore-schema" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" attributeFormDefault="qualified" elementFormDefault="qualified">
  <xs:element name="author">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="first-name" type="xs:string" minOccurs="0" />
        <xs:element name="last-name" type="xs:string" minOccurs="0" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="author" />
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>

The Xsd_after_saved() is woorking perfectlly In Xsd_after_saved(), every place I need to use the XSD, I got from file locally

public void Xsd_after_saved()
{
    XmlReaderSettings settings = n开发者_运维问答ew XmlReaderSettings();
    settings.ValidationEventHandler += this.ValidationEventHandler;

    settings.ValidationType = ValidationType.Schema;
    settings.Schemas.Add(null, XmlReader.Create(@"C:\book.xsd"));
    settings.CheckCharacters = true;

    XmlReader XmlValidatingReader = XmlReader.Create(@"C:\book.xml", settings);

    XmlTextReader Reader = new XmlTextReader(@"C:\book.xml");

    StreamReader SR = new StreamReader(@"C:\book.xsd");

    XmlSchema Schema = new XmlSchema();

    Schema = XmlSchema.Read(SR, ValidationEventHandler);

    XmlValidatingReader ValidatingReader = new XmlValidatingReader(Reader);

    ValidatingReader.ValidationType = ValidationType.Schema;

    ValidatingReader.Schemas.Add(Schema);

    try
    {
        XmlValidatingReader.Read();
        XmlValidatingReader.Close();

        ValidatingReader.ValidationEventHandler += ValidationEventHandler;

        while ((ValidatingReader.Read()))
        {
        }

        ValidatingReader.Close();
    }
    catch (Exception ex)
    {
        ValidatingReader.Close();
        XmlValidatingReader.Close();

    }
}

The Xsd_whithout_saved() is not working In Xsd_whithout_saved(), every place I need the XSD, I got from variable StreamReader named readerXsd whitch come from a string

public void  Xsd_whithout_saved()
{
    //>>>Here is the biggest diference from the method Xsd_after_saved: I manipulate the XSD as string because it will come from database and 
    //it will not allowed to be saved locally
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.Load(@"C:\book.xsd");
    //In the futute, strArquivoInteiro will be fullfill by xsd comming from database as nvarchar(max) and I will not be allowed to save as a file locally
    string strArquivoInteiro = xmlDoc.OuterXml;

    byte[] byteArray = Encoding.ASCII.GetBytes(strArquivoInteiro);
    MemoryStream streamXSD = new MemoryStream(byteArray);
    //<<<

    StreamReader readerXsd = new StreamReader(streamXSD);

    XmlReaderSettings settings = new XmlReaderSettings();
    settings.ValidationEventHandler += this.ValidationEventHandler;

    settings.ValidationType = ValidationType.Schema;
    settings.Schemas.Add(null, XmlReader.Create(readerXsd));
    settings.CheckCharacters = true;

    XmlReader XmlValidatingReader = XmlReader.Create(@"C:\book.xml", settings);

    XmlTextReader Reader = new XmlTextReader(@"C:\book.xml");

    XmlSchema Schema = new XmlSchema();

    //IN THIS LINE I RECEIVED THE XmlException "Root Element is Missing" and I can't understand the reason
    Schema = XmlSchema.Read(readerXsd, ValidationEventHandler);

    XmlValidatingReader ValidatingReader = new XmlValidatingReader(Reader);

    ValidatingReader.ValidationType = ValidationType.Schema;

    ValidatingReader.Schemas.Add(Schema);

    try
    {

        XmlValidatingReader.Read();
        XmlValidatingReader.Close();

        ValidatingReader.ValidationEventHandler += ValidationEventHandler;

        while ((ValidatingReader.Read()))
        {

        }

        ValidatingReader.Close();
    }
    catch (Exception ex)
    {
        ValidatingReader.Close();
        XmlValidatingReader.Close();
    }
}

private void ValidationEventHandler(object sender, ValidationEventArgs args)
{
    //place to deal with xml file no valided
}


Use this method to generate stream from string, (thanks to Cameron MacFarland)

public Stream GenerateStreamFromString(string s)
{
    MemoryStream stream = new MemoryStream();
    StreamWriter writer = new StreamWriter(stream);
    writer.Write(s);
    writer.Flush();
    stream.Position = 0;
    return stream;
}


When you have saved your XML into memory, you need to seek to the start of the stream. Otherwise, when you validate, the validation will start where the save left off - at the end of your data.

Also, you need to make sure that you dispose of readers and streams properly.

//The Xsd_whithout_saved() is not working
//In Xsd_whithout_saved(), every place I need the XSD, I got from variable StreamReader named readerXsd whitch come from a string 
public void  Xsd_whithout_saved()
{
    //>>>Here is the biggest diference from the method Xsd_after_saved: I manipulate the XSD as string because it will come from database and 
    //it will not allowed to be saved locally
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.Load(@"C:\book.xsd");
    //In the futute, strArquivoInteiro will be fullfill by xsd comming from database as nvarchar(max) and I will not be allowed to save as a file locally
    string strArquivoInteiro = xmlDoc.OuterXml;

    byte[] byteArray = Encoding.ASCII.GetBytes(strArquivoInteiro);
    using (MemoryStream streamXSD = new MemoryStream(byteArray))
    using (StreamReader readerXsd = new StreamReader(streamXSD))
    {
        XmlReaderSettings settings = new XmlReaderSettings();
        settings.ValidationEventHandler += this.ValidationEventHandler;
        settings.ValidationType = ValidationType.Schema;
        settings.Schemas.Add(null, XmlReader.Create(readerXsd));
        settings.CheckCharacters = true;

        using (XmlReader XmlValidatingReader = XmlReader.Create(@"C:\book.xml", settings))
        using (XmlTextReader Reader = new XmlTextReader(@"C:\book.xml"))
        {
            XmlSchema Schema = new XmlSchema();

            streamXSD.Seek(SeekOrigin.Begin, 0);
            Schema = XmlSchema.Read(readerXsd, ValidationEventHandler);

            XmlValidatingReader ValidatingReader = new XmlValidatingReader(Reader);
            ValidatingReader.ValidationType = ValidationType.Schema;
            ValidatingReader.Schemas.Add(Schema);

            try
            {
                XmlValidatingReader.Read();
                XmlValidatingReader.Close();

                ValidatingReader.ValidationEventHandler += ValidationEventHandler;

                while ((ValidatingReader.Read()))
                {
                }

                ValidatingReader.Close();
            }
            catch (Exception ex)
            {
                ValidatingReader.Close();
                XmlValidatingReader.Close();
            }
        }
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号