为什么XML NodeType被读作Text而不是Element

时间:2014-02-07 21:01:48

标签: c# xml

这是我尝试从XML中读取的第一次,我遇到的问题是将XML文档的所有元素视为相同的NodeType

示例XML:

<AFElement>
    <Name>InterfaceBuilderTestBreaker01</Name>
    <Template></Template>
    <PIInterface>ModbusE</PIInterface>
</AFElement>

其中所有元素都被视为NodeType.Element,但XmlReader仅将元素PIInterface视为NodeType.Text而不是元素。

XML应该使用的模式包含PIInterface的定义:

<xs:element name="Name" type="xs:string" />
<xs:element name="Template" type="xs:string" />
<xs:element name="PIInterface" type="xs:string"/>

解析xml并将其读入对象的代码类似于:

while (reader.Read())
{
    switch (reader.NodeType)
    {
        case XmlNodeType.Element:
            switch (reader.Name)
            {
                case "PIInterface":
                    // move pointer to element value
                    reader.Read();
                    item.Interface = reader.Value;
                    // move pointer to end element
                    reader.Read();
                    break;
            }
    }
}

有没有理由发生这种情况?我已经看到它同时对待它(元素或文本)我认为快速解决方案是在switch的第一个NodeType.Text中添加一个案例,但这似乎是错误的,因为它应该总是对待它。

任何帮助总是受到赞赏。

更新: 创建一个简单的解析示例后,我发现测试XML文件和实际XML文件之间没有相同的行为。 XML似乎很相似,但不知何故它们不一样。

使用XML:

<?xml version="1.0" encoding="utf-8"?>
<Element xmlns="http://tempuri.org/ExampleParse.xsd">
  <AFElement>
    <Name>ExampleParseName01</Name>
    <Template>ExampleParseTemplate</Template>
    <PIInterface>ModbusE</PIInterface>
    <AFElement>
      <Name>ExampleParseName06</Name>
      <Template>ExampleParseTemplate</Template>
      <PIInterface>ModbusE</PIInterface>
      <AFElement>
        <Name>ExampleParseName07</Name>
        <Template>ExampleParseTemplate</Template>
        <PIInterface>ModbusE</PIInterface>
        <AFElement>
          <Name>ExampleParseName08</Name>
          <Template>ExampleParseTemplate</Template>
          <PIInterface>ModbusE</PIInterface>
        </AFElement>
      </AFElement>
    </AFElement>
  </AFElement>
  <AFElement>
    <Name>ExampleParseName02</Name>
    <Template>ExampleParseTemplate</Template>
    <PIInterface>ModbusE</PIInterface>
  </AFElement>
</Element>

非工作XML:

<Element xmlns="http://tempuri.org/ExampleParse.xsd">
  <AFElement>
    <Name>InterfaceBuilderTestBreaker01</Name>
    <Template></Template>
    <PIInterface>ModbusE</PIInterface>
    <AllAttributes>
      <AFAttribute name="classic">
        <field name="ptclassname" value="ModbusE"/>
        <field name="pointsource" value="InterfaceBuilder01"/>
        <field name="instrumenttag" value="192.168.1.100"/>
      </AFAttribute>
    </AllAttributes>
    <AFElement>
      <Name>InterfaceBuilderTestBreaker02</Name>
      <Template></Template>
      <PIInterface>ModbusE</PIInterface>
      <AllAttributes>
        <AFAttribute name="classic">
          <field name="ptclassname" value="ModbusE"/>
            <field name="pointsource" value="InterfaceBuilder01"/>
            <field name="location1" value="1"/>
            <field name="location2" value="2"/>
            <field name="location3" value=""/>
            <field name="location4" value="2"/>
            <field name="location5" value=""/>
            <field name="instrumenttag" value="192.168.1.100"/>
        </AFAttribute>
      </AllAttributes>
    </AFElement>
    <AFElement>
      <Name>InterfaceBuilderTestBreaker03</Name>
      <Template></Template>
      <PIInterface>ModbusE</PIInterface>
      <AllAttributes>
         <AFAttribute name="classic">
            <field name="ptclassname" value="ModbusE"/>
            <field name="pointsource" value="InterfaceBuilder01"/>
            <field name="location1" value="1"/>
            <field name="location2" value="3"/>
            <field name="location3" value=""/>
            <field name="location4" value="3"/>
            <field name="instrumenttag" value="192.168.1.100"/>
         </AFAttribute>
       </AllAttributes>
    </AFElement>
    <AFElement>
      <Name>InterfaceBuilderTestMeter01</Name>
      <Template></Template>
      <PIInterface>ModbusE</PIInterface>
      <AllAttributes>
         <AFAttribute name="classic">
           <field name="ptclassname" value="ModbusE"/>
           <field name="pointsource" value="InterfaceBuilder02"/>
           <field name="instrumenttag" value="192.168.1.101"/>
           <field name="exdesc" value=""/>
         </AFAttribute>
      </AllAttributes>
     </AFElement>
   </AFElement>
</Element>

我不会认为<AllAttributes>的元素会导致<PIInterface>元素被区别对待。其他差异是从Excel中的单元格中的脚本生成的非工作XML以及我手工放在一起的测试元素。我认为输出中没有任何差异可以解释各种处理或元素。

我错过了什么吗?

注意:XML是元素的层次结构,在解析时应该返回删除层次结构的每个元素的列表。正是出于这个原因,我深入研究了低级接口。我愿意重写解析函数以使用不同的接口,但直到现在它仍按预期工作。

更新2: 根据keshlam的评论,一个完整的示例代码块:

private static void internalParser(XmlReader reader, ref int c, ref ObservableCollection<DataHolder> List)
    {
        DataHolder data = new DataHolder();
        data.Title = "Interface" + c;
        c++;
        while (reader.Read())
        {
            switch (reader.NodeType)
            {
                case XmlNodeType.Element:
                    switch (reader.Name)
                    {
                        case "Name":
                            // move pointer to element value
                            reader.Read();

                            data.InterfaceName = reader.Value;
                            // move pointer to end element
                            reader.Read();
                            break;
                        case "Template":
                            // move pointer to element value
                            reader.Read();
                            data.ElementTemplate = reader.Value;
                            // move pointer to end element
                            reader.Read();
                            break;
                        case "PIInterface":
                            // move pointer to element value
                            reader.Read();
                            data.ElementInterface = reader.Value;
                            // move pointer to end element
                            reader.Read();
                            break;
                        case "AFElement":
                            // create new object for processing
                            internalParser(reader, ref c, ref List);
                            break;
                    }
                    break;
                case XmlNodeType.EndElement:
                    if (reader.Name == "AFElement")
                    {
                        List.Add(data) ;
                        return ;
                    }
                    break;
            }
        }
        return ;
    }

0 个答案:

没有答案