xPath:XmlNode.SelectSingleNode()始终是相同的节点

时间:2014-03-05 17:21:51

标签: c# xml xpath

我一直在尝试让这个查询工作。 我有一个看起来像这样的XML:

<Usuarios>
       <Usuario>
        <username>ghamilton</username>
        <nombre>Catherine Hart</nombre>
        <fechaNacimiento>12-03-1983 00:00:00</fechaNacimiento>
        <nickname>ghamilton</nickname>
        <EventosInscripto/>
        <Amistades>
            <amistad>
                <username>dreed</username>
                <nombre>Ruby Price</nombre>
                <tipo>Aceptado</tipo>
                <nickname>dreed</nickname>
                <fechaNacimiento>23-12-1986 00:00:00</fechaNacimiento>
            </amistad>
            <amistad>
                <username>ffernandez</username>
                <nombre>Michael Rivera</nombre>
                <tipo>Aceptado</tipo>
                <nickname>ffernandez</nickname>
                <fechaNacimiento>07-02-1997 00:00:00</fechaNacimiento>
            </amistad>
        </Amistades>
    </Usuario>
    <!-- a lot more 'Usuario' tags after this one -->
<Usuarios/>

我想做的是让所有Usuarios的值都存储在标签'username','nombre','fechaNacimiento'和昵称中。

为此,我有这段代码:

 XmlNodeList usuarios = xmlDoc.SelectNodes("/Usuarios/Usuario");
            foreach (XmlNode usuario in usuarios)
            {
               //I would use this object to populate a treeview
                rg = new Registrado(
                    xmlNode.SelectSingleNode(@"/username").InnerText,
                    "NA",
                    xmlNode.SelectSingleNode(@"/nombre").InnerText,
                    DateTime.ParseExact(xmlNode.SelectSingleNode(@"/fechaNacimiento").InnerText, "dd-MM-yyyy HH:mm:ss", null),
                    xmlNode.SelectSingleNode(@"/nickname").InnerText,
                    null,
                    null,
                    null,
                    null,
                    true
                    );
             }

但是这个xPath总是选择第一个'usuario'并且它是子节点并且不会循环它们。 实际上,它确实循环遍历整个文档,提供完全匹配的数量,但总是返回相同的数据。

关于为什么我的XPath失败的任何想法?

谢谢!

1 个答案:

答案 0 :(得分:2)

您应该在usuario函数中使用xmlNode而不是Registrado,即

XmlNodeList usuarios = xmlDoc.SelectNodes("Usuarios/Usuario");
foreach (XmlNode usuario in usuarios)
{
   var username = usuario.SelectSingleNode("username").InnerText;
   var nombre = usuario.SelectSingleNode("nombre").InnerText;
   var fechaNacimiento = usuario.SelectSingleNode("fechaNacimiento").InnerText 
   var nickName = usuario.SelectSingleNode("nickname").InnerText;
   var datefechaNacimiento = DateTime.ParseExact(fechaNacimiento, 
                              "dd-MM-yyyy HH:mm:ss", null);

   rg = new Registrado(username, "NA",nombre, datefechaNacimiento,nickName,
                    null, null,null,null,true);
}

同样非常重要的一点是,在处理选择节点时总是确保进行空检查,即不是直接访问节点innerText,而是首先确保它们不是空的,即

if(usuario.SelectSingleNode("username")!=null)
{
   strUsername = usuario.SelectSingleNode("username").InnerText;
}

另外,虽然XmlDocument课程非常强大且有用,但也请看Linq-to-XML