7

我正在尝试从一个简单的 XML 文档中读取元素值并将它们绑定到一个对象,但是我的 XML 文档遇到了问题。我已经对其进行了验证,并且可以确认文档本身没有问题,但是在线扩展了结果:

var nodes = from xDoc in xml.Descendants("RewriteRule")
                select xmlSerializer.Deserialize(xml.CreateReader()) as Url;

显示“XML 文档中存在错误 (0, 0)”

内部异常读取<RewriteRules xmlns=''> was not expected.

我不确定我在这里做错了什么?

我的 XML 如下:

<?xml version="1.0" encoding="utf-8" ?>
<RewriteRules>
    <RewriteRule>
        <From>fromurl</From>
        <To>tourl</To>
        <Type>301</Type>
    </RewriteRule>
</RewriteRules>

加载 XML 文件并尝试对其进行反序列化的代码:-

public static UrlCollection GetRewriteXML(string fileName)
{
    XDocument xml = XDocument.Load(HttpContext.Current.Server.MapPath(fileName));
    var xmlSerializer = new XmlSerializer(typeof(Url));

    var nodes = from xDoc in xml.Descendants("RewriteRule")
                select xmlSerializer.Deserialize(xml.CreateReader()) as Url;

    return nodes as UrlCollection;
}

我的 Url 对象类:-

[Serializable]
[XmlRoot("RewriteRule")]
public class Url
{
    [XmlElement("From")]
    public string From { get; set; }
    [XmlElement("To")]
    public string To { get; set; }
    [XmlElement("Type")]
    public string StatusCode { get; set; }

    public Url()
    {
    }

    public Url(Url url)
    {
        url.From = this.From;
        url.To = this.To;
        url.StatusCode = this.StatusCode;
    }
}

谁能看到我在这里做错了什么?

谢谢

4

3 回答 3

4

我对这from select句话不太熟悉,但似乎你只是传入xmlwhich is the whole XDocument,而不是 the XElementthat is your RewriteRule。这就是为什么您会收到RewriteRules未知的错误消息 -XmlSerializer需要一个RewriteRule.

我设法改写了您的代码LINQ(但如果您知道如何从from select语句中获取单个元素,那应该同样有效)。

这应该给你正确的结果 -rrXElement从返回的Descendants

public static IEnumerable<Url> GetRewriteXML()
{
    XDocument xml = XDocument.Load(HttpContext.Current.Server.MapPath(fileName));

    var xmlSerializer = new XmlSerializer(typeof(Url));

    var nodes = xml.Descendants("RewriteRule")
                .Select(rr => xmlSerializer.Deserialize(rr.CreateReader()) as Url);

    return nodes;
}
于 2013-03-15T09:20:03.270 回答
3

编辑: 您的 Url 类的名称不匹配。您需要将其重命名为“RewriteRule”或以这种方式定义它:

[Serializable]
[System.Xml.Serialization.XmlRoot("RewriteRule")]
public class Url
{
    [XmlElement("From")]
    public string From { get; set; }
    [XmlElement("To")]
    public string To { get; set; }
    [XmlElement("Type")]
    public string StatusCode { get; set; }

    public Url()
    {
    }
    public Url(Url url)
    {
        url.From = this.From;
        url.To = this.To;
        url.StatusCode = this.StatusCode;
    }
}
于 2013-03-14T10:00:08.270 回答
1

当您将其直接反序列化为类的实例时,我的方法更常用。

如果你想使用 XDocument,你可以这样写。我不在我的代码中使用 XDocument。因为我需要反序列化完整的 xml 包,所以我直接使用根节点的反序列化来完成。因此,我在上一篇文章中建议将根节点放在正确的位置。

使用 XDocument,您可以直接访问子部分。这是为您的目的而工作的代码,但可能还有其他人可以帮助您更优雅地设置此代码:

public static UrlCollection GetRewriteXML(string fileName)
    {
        XDocument xml = XDocument.Load(HttpContext.Current.Server.MapPath(fileName));
        var urls = from s in xml.Descendants("RewriteRule")
                   select new
                   {
                       From = (string)s.Element("From").Value,
                       To = (string)s.Element("To").Value,
                       StatusCode = (string)s.Element("Type").Value
                   };
        UrlCollection nodes = new UrlCollection();
        foreach (var url in urls)
        {
            nodes.Add(new Url(url.From, url.To, url.StatusCode));
        }
        return nodes;
    }

[Serializable]
public class Url
{
    [XmlElement("From")]
    public string From { get; set; }
    [XmlElement("To")]
    public string To { get; set; }
    [XmlElement("Type")]
    public string StatusCode { get; set; }

    public Url()
    {
    }

    public Url(string From, string To, string StatusCode)
    {
        this.From = From;
        this.To = To;
        this.StatusCode = StatusCode;
    }

    public Url(Url url)
    {
        url.From = this.From;
        url.To = this.To;
        url.StatusCode = this.StatusCode;
    }
}
于 2013-03-14T12:13:27.563 回答