2013-10-07 110 views
1

我試圖根據XML模式驗證XML節點或片段。我讀這篇文章:通過XSD文件驗證XML節點

Validating xml nodes, not the entire document

,但選擇的解決方案並不像爲我工作。

private void ValidateSubnode(XmlNode node, XmlSchema schema) 
{ 
    XmlTextReader reader = new XmlTextReader(node.OuterXml, XmlNodeType.Element, null); 

    XmlReaderSettings settings = new XmlReaderSettings(); 
    settings.ConformanceLevel = ConformanceLevel.Fragment; 
    settings.Schemas.Add(schema); 
    settings.ValidationType = ValidationType.Schema; 
    settings.ValidationEventHandler += new ValidationEventHandler(XSDValidationEventHandler); 

    XmlReader validationReader = XmlReader.Create(reader, settings); 

    while (validationReader.Read()) 
    { 
    } 
} 

private void XSDValidationEventHandler(object sender, ValidationEventArgs args) 
{ 
    errors.AppendFormat("XSD - Severity {0} - {1}", 
        args.Severity.ToString(), args.Message); 
} 

至極是,據我所看到的,用於驗證碼的完整的文檔,但與「ConformanceLevel.Fragment」

因此,例如,具有一個模式像這樣簡單:

<Customer> 
    <Address> 
    <Line1>Foo</Line1> 
    <Line2>Foo2</Line2> 
    </Address> 
</Customer> 

但是,任何內節點不驗證

<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema'> 
<xsd:element name="Customer"> 
    <xsd:complexType> 
    <xsd:sequence> 
     <xsd:element name="Address"> 
     <xsd:complexType> 
      <xsd:sequence> 
      <xsd:element name="Line1" type="xsd:string" /> 
      <xsd:element name="Line2" type="xsd:string" /> 
      </xsd:sequence> 
     </xsd:complexType> 
     </xsd:element> 
    </xsd:sequence> 
    </xsd:complexType> 
</xsd:element> 
</xsd:schema> 

甲 '根' 節點驗證OK

<Address> 
    <Line1>Foo</Line1> 
    <Line2>Foo2</Line2> 
    </Address> 

我收到錯誤:「‘地址’元素未聲明」

有什麼我失蹤?

+2

僅供參考,你不應該使用'新的XmlTextReader()'或'新的XmlTextWriter()'。自.NET 2.0以來,它們已被棄用。改爲使用'XmlReader.Create()'或'XmlWriter.Create()'。 –

回答

0

您的架構不允許獨立的Address元素,所以當您只通過驗證失敗時。

修改您的模式是這樣的:

<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema'> 
    <xsd:element name="Address"> 
    <xsd:complexType> 
     <xsd:sequence> 
     <xsd:element name="Line1" type="xsd:string" /> 
     <xsd:element name="Line2" type="xsd:string" /> 
     </xsd:sequence> 
    </xsd:complexType> 
    </xsd:element> 
    <xsd:element name="Customer"> 
    <xsd:complexType> 
     <xsd:sequence> 
     <xsd:element ref="Address"/> 
     </xsd:sequence> 
    </xsd:complexType> 
    </xsd:element> 
</xsd:schema> 

驗證XML與XSD的片段並未真正發揮作用:同一元素可以有效還是無效 - 或有不同的有效結構 - 這取決於它在哪裏在與XSD匹配的文檔中,驗證獨立元素是不可能的(通常情況下)。

+0

那麼,我是否必須將XSD更改爲部分驗證節點?沒有其他解決方案?這只是一個例子,但最初的模式非常複雜,只有一個根元素。 http://www.iso20022.org/message_archive.page?#PaymentsInitiation3 此XSD僅用於驗證完整文檔,但我想開發一個使用TDD創建XML編譯文檔的工具,所以我想成爲能夠單獨測試每個元素,因爲我開發... :( – Kaikus

+1

您必須更改XSD ...沒有通用解決方案,請參閱我的擴展答案。 – MiMo