2011-09-21 31 views
5

Tôi đang sử dụng lược đồ XSD lồng nhau để xác thực hợp lệ tài liệu XML. Các XSD được nhập khẩu sử dụng các vùng tên đích của riêng chúng và tôi có thể xác thực XML mẫu được đưa ra dưới đây bằng cách sử dụng Liquid XML Studio. Nhưng khi tôi chạy xác thực bằng cách sử dụng mã C# của tôi dưới đây, nó không thành công với lỗi khai báo kiểu (xem bên dưới). Tôi có dành rất nhiều thời gian cố gắng tìm ra, nhưng không có may mắn:Lỗi xác thực XML bằng lược đồ XSD lồng nhau - Loại không được khai báo

chính XSD Schema (DataItem.xsd):

<?xml version="1.0" encoding="utf-8" ?> 
<xs:schema xmlns:DataNumeric="Doc.DataNumeric" xmlns:DataYesNo="Doc.DataYesNo" attributeFormDefault="qualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:import schemaLocation="DataNumeric.xsd" namespace="Doc.DataNumeric" /> 
    <xs:import schemaLocation="DataYesNo.xsd" namespace="Doc.DataYesNo" /> 
    <xs:complexType name="tDataItem"> 
     <xs:choice> 
     <xs:element name="DataNumeric" type="DataNumeric:tDataNumeric" /> 
     <xs:element name="DataYesNo" type="DataYesNo:tDataYesNo" /> 
     </xs:choice> 
    </xs:complexType> 
    <xs:element name="DataItem" type="tDataItem" /> 
</xs:schema> 

Bao gồm XSD Schema (DataNumeric.xsd):

**<?xml version="1.0" encoding="utf-8" ?> 
<xs:schema xmlns:DataNumeric="Doc.DataNumeric" elementFormDefault="qualified" targetNamespace="Doc.DataNumeric" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:complexType name="tDataNumeric"> 
    <xs:sequence> 
     <xs:element name="Answer" type="xs:double" /> 
    </xs:sequence> 
    </xs:complexType> 
    <xs:element name="DataNumeric" type="DataNumeric:tDataNumeric" /> 
</xs:schema>** 

XML:

<DataItem> 
    <DataNumeric xmlns:DataNumeric="Doc.DataNumeric"> 
    <DataNumeric:Answer>37.8</DataNumeric:Answer> 
    </DataNumeric> 
</DataItem> 

Validation Lỗi:

XmlSchemaValidationException: Loại 'Doc.DataNumeric: tDataNumeric' không được công bố.

C# Validation Code:

XDocument xDoc = XDocument.Parse(xxxxxxx); 
string xsdPath = ConfigUtils.GetXsdPath(XsdSchemaIdentifier.HHDataItem); 
FileStream fs = new FileStream(xsdPath, FileMode.Open); 
XmlReader reader = XmlReader.Create(fs); 
XmlSchemaSet xss = new XmlSchemaSet(); 
xss.Add("", reader); 
fs.Close(); 
fs.Dispose(); 

xDoc.Validate(xss, null); 

Trả lời

5

tôi đã tìm thấy các vấn đề sau một ngày bực bội và một nửa số lần lặp lại. Thay đổi:

FileStream fs = new FileStream(xsdPath, FileMode.Open); 
XmlReader reader = XmlReader.Create(fs); 
XmlSchemaSet xss = new XmlSchemaSet(); 
xss.Add("", reader); 

để

XmlSchemaSet xss = new XmlSchemaSet(); 
xss.Add("", xsdPath); 

giải quyết vấn đề. Tuy nhiên tôi vẫn đang tìm câu trả lời cho TẠI SAO? Cả hai đều là các cách hợp lệ để thêm lược đồ vào tập hợp lược đồ (tức là 2 quá tải).

+5

Lý do không thành công là XSD của bạn nhập các XSD khác. Khi bạn đang sử dụng một 'XmlReader', nó không có ý tưởng gì về vị trí của đầu vào' Stream' bên dưới, và vì vậy nó không có bất kỳ cách nào để tìm các mục nhập khẩu. Khi bạn cung cấp đường dẫn đến tệp lược đồ đến 'XmlSchemaSet', nó có thể thực hiện việc định vị riêng của nó dựa trên đường dẫn đó. – arootbeer

1

arootbeer là đúng về cách xsd của bạn nhập một xsd khác. Tuy nhiên một giải pháp khác là thêm xsd đã nhập vào XmlSchemaSet trước, sau đó thêm xsd đang thực hiện việc nhập thực tế.

//Xsd file that is being imported 
FileStream importedXsdStream = new FileStream(importedXsdPath, FileMode.Open); 
XmlReader xmlReader = XmlReader.Create(importedXsdStream); 
XmlSchemaSet xmlSchemaSet = new XmlSchemaSet(); 
xmlSchemaSet.Add("NameSpace.SomeNameSpace", xmlReader); 

//Your code 
FileStream fs = new FileStream(xsdPath, FileMode.Open); 
XmlReader reader = XmlReader.Create(fs); 
XmlSchemaSet xss = new XmlSchemaSet(); 
xss.Add("", reader); 

Lưu ý Tôi đặt Không gian tên làm tham số đầu tiên khi thêm xsd đã nhập vào XmlSchemaSet. Điều này có thể cần thiết tùy thuộc vào nếu có lỗi với không gian tên đích không khớp với không gian tên được cung cấp trong xsd đã nhập.

Các vấn đề liên quan