XmlReader - 只读 "child xpath axis"
XmlReader - only read "child xpath axis"
您好,我有 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="&&[A-F0-9]" />
</Record>
</Record>
</MyRoot>
一旦 XmlReader
位于 MyRoot
之上,我如何才能只循环遍历 MyRoot
的直接 children(在这种情况下,<Record Name="Header" >
和 <Record Name="Body" MaxOccurs="0">
)。我将这些节点的 xml 递归地委托给另一个 class。
在考虑重复问题之前,请确保 OP 没有询问 grand-children 或除 children
的 xpath 轴之外的其他一些 node-set。我找不到与这个问题完全匹配的问题,而且 XmlReader
似乎一直想先深入。
我想做的是交出 XmlReader
并让正在消耗 child xml 的 child object 交还给它对我来说,正确指出了获得下一个 child 所需的位置。那会很甜蜜。
这是有效的。抱歉,它不是 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();
}
您好,我有 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="&&[A-F0-9]" />
</Record>
</Record>
</MyRoot>
一旦 XmlReader
位于 MyRoot
之上,我如何才能只循环遍历 MyRoot
的直接 children(在这种情况下,<Record Name="Header" >
和 <Record Name="Body" MaxOccurs="0">
)。我将这些节点的 xml 递归地委托给另一个 class。
在考虑重复问题之前,请确保 OP 没有询问 grand-children 或除 children
的 xpath 轴之外的其他一些 node-set。我找不到与这个问题完全匹配的问题,而且 XmlReader
似乎一直想先深入。
我想做的是交出 XmlReader
并让正在消耗 child xml 的 child object 交还给它对我来说,正确指出了获得下一个 child 所需的位置。那会很甜蜜。
这是有效的。抱歉,它不是 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();
}