繁体   English   中英

我正在尝试在.NET环境中使用C#解析XML文件,并且该文件不断跳过元素

[英]I am trying to parse an XML file using C# in the .NET environment and it keeps skipping over elements

所以这就是我要解析的XML的一部分的样子:

<azsa:Views>
   <azsa:Spatial_Array>
      <azsa:Spatial>
         <azsa:ViewName>Spatial</azsa:ViewName>
            <azsa:BBox>
               <azsa:PointLo>
                 <azsa:x>0</azsa:x>
                 <azsa:y>0</azsa:y>
                 <azsa:z>0</azsa:z>
                </azsa:PointLo>
               <azsa:PointHi>
                 <azsa:x>2925</azsa:x>
                 <azsa:y>3375</azsa:y>
                 <azsa:z>2775</azsa:z>
               </azsa:PointHi>
             </azsa:BBox>
       </azsa:Spatial>
    </azsa:Spatial_Array>
</azsa:Views>

我必须读取PointHi和PointLo的x,y和z坐标

我正在使用XMLReader()类执行任务。

XmlTextReader reader = new XmlTextReader(openFileDialog1.FileName);

 while (reader.Read())
 {
   reader.ReadToFollowing("azsa:Views");
   reader.ReadToFollowing("azsa:Spatial_Array");
   reader.ReadToFollowing("azsa:Spatial");
   reader.ReadToFollowing("azsa:ViewName");
   reader.ReadToFollowing("azsa:BBox");
   reader.ReadToFollowing("azsa:PointLo");
   reader.ReadToFollowing("azsa:x");
   low[0] = (int)(Double.Parse(reader.ReadElementString()));
   reader.ReadToFollowing("azsa:y");
   low[1] = (int)(Double.Parse(reader.ReadElementString()));
   reader.ReadToFollowing("azsa:z");
   low[2] = (int)(Double.Parse(reader.ReadElementString()));
   reader.ReadToFollowing("azsa:PointHi");
   reader.ReadToFollowing("azsa:x");
   high[0] = (int)(Double.Parse(reader.ReadElementString()));
   reader.ReadToFollowing("azsa:y");
   high[1] = (int)(Double.Parse(reader.ReadElementString()));
   reader.ReadToFollowing("azsa:z");
   high[2] = (int)(Double.Parse(reader.ReadElementString()));
}

读取器运行良好,直到到达PointLo中的第一个x,然后才跳至PointHi中的y。 我曾尝试使用后代,子树和readinnerxml,但它仍然做同样的事情。

注意:1. while循环中有更多代码可读取XML的其余部分,但对于此问题而言不是必需的,因此我没有在帖子中包含它。 2.无法更改XML的组织方式,因为这是我执行的任务要求存储它们的方式。 3. XMLReader是首选方法,因为我正在处理大量文档,并且没有使用此缓存的范围。

读取子树时,我有一个相当类似的问题。 在这种情况下,解决方案是处置子树XmlReaders。 当然,这里的情况稍有不同,但是您可以考虑采用以下方法(请注意,为了简化测试,我删除了元素前缀,并读取了XML字符串而不是文件)?

它看起来很丑陋,但这只是概念上的证明,可以加以整理。 它还缺少适当的错误检查,但这再次只是出于演示目的。 它至少解析出不同的点值。

附带说明一下,我认为可以通过创建表示XML流中不同组件(或对象)的类,并使这些类负责解析其自身的属性,来消除很多丑陋的事物。

(我敢肯定)只有一种方法可以给猫皮...

private void ParseXml(string xml)
{
    double[] low = null;
    double[] hi = null;

    using (StringReader stringReader = new StringReader(xml))
    {
        using (XmlReader xmlReader = XmlReader.Create(stringReader))
        {
            while (xmlReader.Read())
            {
                if (xmlReader.NodeType != XmlNodeType.Element) continue;

                if (xmlReader.Name == "PointLo")
                {
                    low = ParsePoint(xmlReader);
                }
                else if (xmlReader.Name == "PointHi")
                {
                    hi = ParsePoint(xmlReader);
                }
            }
        }
    }
}

private double[] ParsePoint(XmlReader xmlReader)
{
    double[] point = new double[3];

    using (XmlReader pointReader = xmlReader.ReadSubtree())
    {
        while (pointReader.Read())
        {
            if (pointReader.NodeType != XmlNodeType.Element) continue;

            if (pointReader.Name == "x")
            {
                point[0] = GetDimensionValue(pointReader);
            }
            else if (pointReader.Name == "y")
            {
                point[1] = GetDimensionValue(pointReader);
            }
            else if (pointReader.Name == "z")
            {
                point[2] = GetDimensionValue(pointReader);
            }
        }
    }

    return point;
}

private double GetDimensionValue(XmlReader reader)
{
    using (XmlReader dimensionReader = reader.ReadSubtree())
    {
        dimensionReader.Read();

        return reader.ReadElementContentAsDouble();
    }
}

因此,正如我在对曼德森解决方案的评论中提到的那样,由于某种原因,它不将y元素视为元素,而是将其视为文本元素,我对ParsePoint()中的while循环进行了以下更改

                 while (pointReader.Read())
                  {
                    if (pointReader.NodeType == XmlNodeType.Element || pointReader.NodeType== XmlNodeType.Text)
                     {

                      if (pointReader.Name == "azsa:x")
                       {
                          point[0] = pointReader.ReadElementContentAsDouble();
                       }
                      else if (pointReader.Name == "")
                       {
                          point[1] = Double.Parse(pointReader.Value);
                       }
                     else if (pointReader.Name == "azsa:z")
                       {
                     point[2] = pointReader.ReadElementContentAsDouble();
                       }
                    }
                 }

虽然我并不是说这是理想的方法,但是它适用于我正在处理的XML文件。 我还删除了GetDimensionValue方法,只读取了此方法本身中的值/元素内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM