XmlReader - 只读“子xpath轴”

时间:2015-02-17 20:33:13

标签: .net ixmlserializable

您好,我的xml具有相同的嵌套元素。它是递归的(快乐!)

像这样:

<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" >和{{1} })。我正在委托将这些节点的xml以递归方式读取到另一个类。

在考虑重复问题之前,请确保OP不会询问除<Record Name="Body" MaxOccurs="0">的xpath轴之外的孙子或其他节点集。我无法找到这个问题的完全匹配,而children似乎希望始终保持深度。

我喜欢做的是交出XmlReader并让孩子对象消耗掉孩子xml,然后将它指向我指向下一个孩子所需的位置。那会很好。

1 个答案:

答案 0 :(得分: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();
}