为什么我的xml doc被认为是一个元素?

时间:2014-09-17 15:57:39

标签: c# xml xpath

我正在尝试将xml文件加载到xmlDocument,但收到错误,导致无法转换xmlelement to a xmldocument为什么?

XML

<VR>
  <SubscriberID>xxxx</SubscriberID>
  <EmailAddress>m@gmail.com</EmailAddress>
  <FirstName>m</FirstName>
  <LastName>x</LastName>
  <State>CO</State>
  <Country/>
  <BirthDate>11/16/3004</BirthDate>
  <SendEmail>False</SendEmail>
  <Preference Value="true" Key="life"/>
  <Preference Value="true" Key="yo"/>
</VR>

C#测试

        preferenceHelper target = new preferenceHelper(); // TODO: Initialize to an appropriate value
        XmlDocument docIn = new XmlDocument();
        docIn.Load(@"C:/INTG/trunk/src/VRI.Integration.Email/Test/xmlIn.xml");
        XmlDocument expected = null; // I know this will fail in the test, but it should compile, right?
        XmlDocument actual;
        actual = target.preferencesXmlDoc(docIn);
        Assert.AreEqual(expected, actual);
        Assert.Inconclusive("Verify the correctness of this test method.");

C#功能

public class preferenceHelper
    {
        public preferenceHelper() { }

        XmlDocument docOut = new XmlDocument();
        public XmlDocument preferencesXmlDoc(XmlDocument docIn)
        {
            foreach (XmlDocument root in docIn.SelectNodes("//VR"))
            {
                foreach (XmlDocument node in root.SelectNodes("//Preference"))
                {
                    XmlNode Name = docIn.CreateElement("Name");
                    Name.InnerText = node.InnerText = node.Attributes["Key"].Value;
                    XmlNode Value = docIn.CreateElement("Value");
                    Value.InnerText = node.InnerText = node.Attributes["Value"].Value;
                    docOut.CreateElement("Property").AppendChild(Name).AppendChild(Value);
                }
            }
            return docOut;
        }

    }

错误

Test method Test.preferenceHelperTest.preferencesXmlDocTest threw exception: 
System.InvalidCastException: Unable to cast object of type 'System.Xml.XmlElement' to type 'System.Xml.XmlDocument'.

如果需要,我不会在xmlIn中添加命名空间 - 如何加载我的xml文件?

失败的地方: actual = target.preferencesXmlDoc(docIn);

由于

4 个答案:

答案 0 :(得分:3)

问题就在这里:

foreach (XmlDocument root in docIn.SelectNodes("//VR"))

在这里:

foreach (XmlDocument node in root.SelectNodes("//Preference"))



XmlNode.SelectNodes()会返回XmlNodeListIEnumerable XmlNodes。它不会包含任何XmlDocument个。



所以这样做:

foreach (XmlNode root in docIn.SelectNodes("//VR"))

和此:

foreach (XmlElement node in root.SelectNodes("//Preference"))

答案 1 :(得分:2)

你的问题在于这些陈述:

foreach (XmlDocument root in SelectNodes(...))

foreach隐式将序列中的每个值强制转换为您指定的类型。声明扩大到:

using(var e = sequence.GetEnumerator())
{
    while (e.MoveNext())
    {
        XmlDocument v = (XmlDocument)e.Current;
        // loop body
    }
}

导致InvalidCastException崩溃的原因是您选择的节点类型为XmlElement,而不是XmlDocument。要解决此问题,只需将foreach语句中的类型切换为XmlElement

您还可以通过使用XPath访问Preference元素来提高可读性,将两个循环替换为单个:

foreach (XmlElement node in docIn.SelectNodes("/VR/Preference"))

您的外部SelectNodes循环实际上是完全冗余的,因为//Preference将从文档的根目录中获取所有Preference个后代,而不仅仅是来自该特定子VR。

答案 2 :(得分:1)

XmlDocument.SelectNodes(&#34; // VR&#34;)返回XmlNodeList,而不是XmlDocument。因此,至少您需要将代码更改为:

public XmlDocument preferencesXmlDoc(XmlDocument docIn)
{
    foreach (XmlNode root in docIn.SelectNodes("//VR"))
    {
        foreach (XmlNode node in root.SelectNodes("//Preference"))
        {

答案 3 :(得分:0)

文档通常有一个标题:

<?xml version="1.0"?>

没有标题,它被视为元素。

尝试添加一个。