XMLファイルを検証するために、XSDファイルの階層を使用しています。その中にはdtdファイルが含まれています。私は、検証フラグProcessInlineSchema
とProcessSchemaLocation
を設定することによって、XMLファイルのschemaLocationで参照されるスキーマに基づいてそれを成功裏に実行することができました。C#でDTD宣言を含むXSDスキーマを使用してXMLを検証する
私のシナリオでは、構築しているアプリケーションでXSDファイルを配信する必要があるため、schemaLocationを無視する必要があります(Web上のどこかを指すようになります)。 XMLファイルは標準です。
は、私は私の問題をテストするために簡単な例を作成した - 私は、次のファイルがあります。<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xs:schema [
<!ENTITY % inc.dtd SYSTEM "inc.dtd">
%inc.dtd;
]>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="ro:sopa:inc">
<xs:simpleType name="testInc">
<xs:restriction base="xs:string">
<xs:pattern value="&test;"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
が
をinc.dtd included.xsd<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="ro:sopa:main" xmlns:main="ro:sopa:main" xmlns:inc="ro:sopa:inc" >
<xs:import namespace="ro:sopa:inc" schemaLocation="included.xsd"/>
<xs:element name="test" type="main:testType"/>
<xs:complexType name="testType">
<xs:sequence>
<xs:element name="test1" type="inc:testInc" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
main.xsdを
<!ENTITY digit "[0-9]{1}">
<!ENTITY alnum "[A-Z]{1}">
<!ENTITY test "&alnum;-&digit;">
サンプルXMLファイルは:
<main:test xsi:schemaLocation="ro:sopa:main D:\schemas\main.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:main="ro:sopa:main">
<test1>A-4</test1>
</main:test>
私が直接XMLファイルで指さスキーマに対して検証する場合は、それが正常に動作します:
List<string> report = new List<string>();
XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
settings.DtdProcessing = DtdProcessing.Parse;
settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
settings.ValidationEventHandler += new ValidationEventHandler(delegate(object snd, ValidationEventArgs e2)
{
report.Add(e2.Message);
});
XmlReader reader = XmlReader.Create(fileName, settings);
while (reader.Read());
reader.Close();
をしかし、私は手動でXmlSchemaSetを設定しようとする場合、それは動作しません。
public static string schemaUrl = @"D:\schema\main.xsd";
public static string fileName = @"D:\somewhere\testProd1.xml";
public static void Main(string[] args)
{
List<string> report = new List<string>();
XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
settings.DtdProcessing = DtdProcessing.Parse;
settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
settings.Schemas = ProvideSchemaSet(report);
settings.ValidationEventHandler += new ValidationEventHandler(delegate(object snd, ValidationEventArgs e2)
{
report.Add(e2.Message);
});
XmlReader reader = XmlReader.Create(fileName, settings);
while (reader.Read()) ;
reader.Close();
}
public static XmlSchemaSet ProvideSchemaSet(List<string> schemaLoadErrors)
{
XmlSchemaSet schemas = new XmlSchemaSet();
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Parse;
XmlReader schemaReader = XmlReader.Create(schemaUrl, settings);
XmlSchema schema = XmlSchema.Read(schemaReader, delegate(object sender, ValidationEventArgs e)
{
schemaLoadErrors.Add(e.Message);
});
schemas.Add(schema);
schemaReader.Close();
schemas.Compile();
return schemas;
}
これは、オブジェクトtest1が存在しないことを示すschemas.Compile()でクラッシュします。これは、私がdtdを使用する場合にのみ発生します。私がDTDをスキーマから取り出しても正しく動作します。
私がインターネットで検索したのは、具体的にはXSD検証またはDTD検証に関するものでしたが、これについての解決策は見つかりませんでした。助言がありますか?
注:私が扱う必要があるスキーマとDTDは標準化されているため、決して変更することはできません。