2015-02-17 42 views
0

你好我有xml嵌套元素是相同的。它是遞歸(快樂!)XmlReader - 只能讀取「子xpath軸」

像這樣:

<MyRoot> 
    <Record Name="Header" > 
    <Field Type="Pattern" Expression=";VR_PANEL_ID,\s+" /> 
    <Field Name="PanelID" Type="Pattern" Expression="\d+"/> 
    <Field Type="Pattern" Expression="," /> 
    <Field Name="ProductionDateTime" Type="Pattern" Expression=".+?(?=,)" /> 
    <Field Type="Pattern" Expression=".+?" /> 
    </Record> 
    <Record Name="Body" MaxOccurs="0"> 
    <Record Name="Command" Compositor="Choice"> 
     <Record Name="Liquid Status" > 
     <Record Name="Header" > 
      <Field Type="Pattern" Expression="i30100" /> 
      <Field Name="DateTime" Type="Pattern" Expression="\d{10}"/> 
     </Record> 
     <Record Name="Data" MinOccurs="0" MaxOccurs="0"> 
      <Field Name="DeviceNum" Type="Pattern" Expression="\d\d" /> 
      <Field Name="Status" Type="Pattern" Expression="\d{4}" /> 
     </Record> 
     </Record> 
    </Record> 
    <Record Name="Footer" > 
     <Field Type="Pattern" Expression="&amp;&amp;[A-F0-9]" /> 
    </Record> 
    </Record> 
</MyRoot> 

一旦XmlReader定位在MyRoot,哪能只是環通只是MyRoot直接孩子(在這種情況下,<Record Name="Header" ><Record Name="Body" MaxOccurs="0">)。我將這些節點的xml委託給另一個類遞歸地讀取。

在考慮重複問題之前,請確保OP沒有詢問除了xpath軸children以外的其他節點集。我找不到這個問題的完全匹配,並且XmlReader似乎想要始終保持深入。

我想做的事情是交出XmlReader,並讓孩子的對象消耗孩子的xml手把它帶回我指向需要的地方,以獲得下一個孩子。這將是甜蜜的。

+0

你是否限制使用'XmlReader'? – VMAtm 2015-02-17 20:39:03

+0

@VMAtm,我正在實現'IXmlSerializable' – toddmo 2015-02-17 20:43:19

回答

0

這是什麼工作。對不起,這不是100%通用的,但它可能會給你一個想法:

public void ReadXml(System.Xml.XmlReader reader) 
{ 
    ReadAttributes(this, reader); 
    reader.Read(); //advance 
    switch (reader.Name) { 
     case "Record": 
     case "Field": 
      break; 
     default: 
      reader.MoveToContent(); //skip other nodes 
      break; 
    } 

    if (reader.Name == "Record") { 
     do { 
      LexicalRecordType Record = new LexicalRecordType(); 
      Record.ReadXml(reader); 
      Records.Add(Record); 
      //.Read() 
     } while (reader.ReadToNextSibling("Record")); //get next record 
    } else if (reader.Name == "Field") { 
     do { 
      LexicalField Field = Deserialize(reader.ReadOuterXml, typeof(LexicalField)); 
      Add(Field); 
     } while (reader.Name == "Field"); 
    } 
} 

public void ReadAttributes(object NonSerializableObject, System.Xml.XmlReader XmlReader) 
{ 
    XmlReader.MoveToContent(); 
    for (int Index = 0; Index <= XmlReader.AttributeCount - 1; Index++) { 
     XmlReader.MoveToAttribute(Index); 
     PropertyInfo PropertyInfo = NonSerializableObject.GetType.GetProperty(XmlReader.LocalName); 
     PropertyInfo.SetValue(NonSerializableObject, ConvertAttribute(XmlReader.Value, PropertyInfo.PropertyType), null); 
    } 
    XmlReader.MoveToContent(); 
}