Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我试图在.NET环境中使用C#解析XML文件,但它总是跳过元素_C#_.net_Xml_Xml Parsing_Xmlreader - Fatal编程技术网

我试图在.NET环境中使用C#解析XML文件,但它总是跳过元素

我试图在.NET环境中使用C#解析XML文件,但它总是跳过元素,c#,.net,xml,xml-parsing,xmlreader,C#,.net,Xml,Xml Parsing,Xmlreader,这就是我试图解析的XML的一部分的样子: <azsa:Views> <azsa:Spatial_Array> <azsa:Spatial> <azsa:ViewName>Spatial</azsa:ViewName> <azsa:BBox> <azsa:PointLo> <azsa:x

这就是我试图解析的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>
读卡器工作正常,直到它到达PointLo中的第一个x,然后跳到PointHi中的y。我尝试过使用子体、子树和readinnerxml,但它仍然做同样的事情

注:1。while循环中有更多的代码用于读取XML的其余部分,但这对于这个问题不是必需的,所以我没有在文章中包含它。 2.改变XML的组织方式是不可能的,因为这是我正在执行的任务所需要的存储方式。
3.XMLReader是一种更好的方法,因为我正在处理大量的文档,并且没有使用缓存的余地。

不久前我在读取子树时遇到了一个非常类似的问题。该场景中的解决方案是处置子树XmlReaders。当然,这里的情况略有不同,但你能考虑一种方法,如下面(注意,我删除了元素前缀的测试简单,以及读取XML字符串,而不是一个文件)?< / P> 它看起来确实很难看,但这更像是概念的证明,可以稍微整理一下。它还缺少适当的错误检查,但这也是出于演示目的。它至少会解析出不同的点值

顺便说一句,我认为通过创建类来表示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();
    }
}

因此,正如我在对manderson解决方案的评论中提到的,出于某种原因,它没有将y元素视为元素,而是将其视为文本元素,我对ParsePoint()中的while循环做了以下更改


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

旁注:文章中的原因3并没有令人信服的文字——“大量文档”并不能证明像我书中的XmlReader这样痛苦的API是正确的,但也许你指的是“大量大型文档”读者可能是个不错的选择。是的,对不起,我指的是大量的大型文档。这实际上比我的要好,但出于某种原因,它仍然跳过了y值。我正在努力想办法解决这个问题,但仍然比我想象的要多,所以非常感谢你们!当它到达y时,它认为pointReader.NodeType不是一个元素,所以跳过它。我完全修复了它。我只是改变了它处理指针阅读器的方式。因此,它在if-else循环的else部分而不是while循环中执行,while循环使用标志值作为条件。它就像一个符咒。非常感谢你为我指明了正确的方向。
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();
    }
}
                 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();
                       }
                    }
                 }