如何在运行时验证xml对xsd而不保存本地文件夹中的xsd文件?

时间:2010-06-21 14:31:49

标签: c# xml xsd

我的目标是针对字符串变量中的xsd whitch验证xml文件。 Ps。:我周五已经写了一个3072697的问题。但我今天无法添加此代码。

是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>

Xsd_after_saved()完美无缺 在Xsd_after_saved()中,我需要使用XSD的每个地方,我从本地获取文件

public void Xsd_after_saved()
{
    XmlReaderSettings settings = new 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();

    }
}

Xsd_whithout_saved()无效 在Xsd_whithout_saved()中,我需要XSD的每个地方,我从变量StreamReader获得名为readerXsd whitch来自字符串

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
}

2 个答案:

答案 0 :(得分:4)

使用此方法从字符串生成流,(感谢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;
}

答案 1 :(得分:3)

将XML保存到内存后,需要寻找流的开头。否则,验证时,验证将从保存中断的位置开始 - 在数据末尾。

此外,您需要确保正确处理读者和流。

//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();
            }
        }
    }
}