【问题标题】:Sitemap doesn't show as xml站点地图不显示为 xml
【发布时间】:2013-12-23 23:49:17
【问题描述】:

我的站点地图生成有以下类:

public class SitemapItem
{
    public SitemapItem(string url)
    {
        this.Url = url;
        this.AlternateLinks = new List<SiteMapAlternateLink>();
    }

    public string Url { get; set; }

    public DateTime? LastModified { get; set; }

    public ChangeFrequency? ChangeFrequency { get; set; }

    public float? Priority { get; set; }

    public List<SiteMapAlternateLink> AlternateLinks { get; set; }
}

还有:

public class SiteMapAlternateLink
{
    public SiteMapAlternateLink(string url, string language)
    {
        this.Url = url;
        this.Language = language;
    }

    public string Url { get; set; }

    public string Language { get; set; }
}

现在在我的控制器中,我填写一个 SitemapItems 列表并使用以下代码从控制器返回它:

public class XmlSitemapResult : ActionResult
{
    private XNamespace nsSitemap = "http://www.sitemaps.org/schemas/sitemap/0.9";
    private XNamespace nsXhtml = "http://www.w3.org/1999/xhtml";

    private IEnumerable<SitemapItem> _items;

    public XmlSitemapResult(IEnumerable<SitemapItem> items)
    {
        _items = items;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        string encoding = context.HttpContext.Response.ContentEncoding.WebName;
        XDocument sitemap = new XDocument(new XDeclaration("1.0", encoding, "yes"),
             new XElement(nsSitemap + "urlset", new XAttribute(XNamespace.Xmlns + "xhtml", nsXhtml),
                  from item in _items
                  select CreateItemElement(item)
                  )
             );

        context.HttpContext.Response.ContentType = "application/xml";
        context.HttpContext.Response.Charset = encoding;
        context.HttpContext.Response.Flush();
        context.HttpContext.Response.Write(sitemap.Declaration + sitemap.ToString());
    }

    private XElement CreateItemElement(SitemapItem item)
    {
        XElement itemElement = new XElement(nsSitemap + "url", new XElement(nsSitemap + "loc", item.Url.ToLower()));

        if (item.LastModified.HasValue)
            itemElement.Add(new XElement(nsSitemap + "lastmod", item.LastModified.Value.ToString("yyyy-MM-dd")));

        if (item.ChangeFrequency.HasValue)
            itemElement.Add(new XElement(nsSitemap + "changefreq", item.ChangeFrequency.Value.ToString().ToLower()));

        if (item.Priority.HasValue)
            itemElement.Add(new XElement(nsSitemap + "priority", item.Priority.Value.ToString(CultureInfo.InvariantCulture)));

        foreach (var alternateLink in item.AlternateLinks)
        {
            itemElement.Add(new XElement(nsXhtml + "link", 
                new XAttribute("rel", "alternate"),
                new XAttribute("hreflang", alternateLink.Language),
                new XAttribute("href", alternateLink.Url)));
        }

        return itemElement;
    }
}

现在的问题是在我的浏览器中我不会将 XML 视为 XML。我只会看到标准 XML 查看器无法查看的文本。这发生在所有浏览器中,并且似乎从我添加 xhtml 架构的那一刻起就发生了。

希望有人看到问题,提前谢谢!

编辑:如果我删除所有与 xhtml 相关的内容,浏览器会将其显示为 xml。有什么想法吗?

EDIT2: html:

 <urlset xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>http://localhost:11149/en</loc>
    <changefreq>hourly</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="http://localhost:11149/en"/>
    <xhtml:link rel="alternate" hreflang="nl" href="http://localhost:11149/nl"/>
  </url>
  <url>
    <loc>http://localhost:11149/en/buyandsell</loc>
    <changefreq>weekly</changefreq>
    <priority>1</priority>
    <xhtml:link rel="alternate" hreflang="en" href="http://localhost:11149/en/BuyAndSell"/>
    <xhtml:link rel="alternate" hreflang="nl" href="http://localhost:11149/nl/BuyAndSell"/>
  </url>
  <url>
    <loc>http://localhost:11149/en/partner</loc>
    <changefreq>weekly</changefreq>
    <priority>0.5</priority>
    <xhtml:link rel="alternate" hreflang="en" href="http://localhost:11149/en/Partner"/>
    <xhtml:link rel="alternate" hreflang="nl" href="http://localhost:11149/nl/Partner"/>
  </url>
  <url>
    <loc>http://localhost:11149/en/news</loc>
    <lastmod>2013-12-06</lastmod>
    <changefreq>daily</changefreq>
    <priority>0.6</priority>
    <xhtml:link rel="alternate" hreflang="en" href="http://localhost:11149/en/News"/>
    <xhtml:link rel="alternate" hreflang="nl" href="http://localhost:11149/nl/News"/>
  </url>
</urlset>

【问题讨论】:

  • 你需要显示你的控制器方法。还有原始 HTTP 是什么样的?
  • @Liam 我添加了 html,控制器与它无关,因为它返回一个 XmlSiteMapResult,除了填充项目列表之外没有任何反应。
  • 如果您查看站点地图 (xdocument),它看起来是否像格式良好的 XML?
  • 根据 MSDN,这是一个有效的站点地图:msdn.microsoft.com/en-us/library/yy2ykkab(v=vs.100).aspx
  • 确实,只要我让网站验证站点地图,它就会完美验证。虽然我希望每当客户访问站点地图时,他都会使用浏览器 xml 查看器看到它。

标签: c# asp.net xml asp.net-mvc sitemap


【解决方案1】:

以下是我们为 autoquoter.com 生成站点地图的方法。见http://www.autoquoter.com/aq/sitemap.xml

        var sitemap = new XDocument(
            new XDeclaration("1.0", "utf-8", "yes"),
            new XProcessingInstruction("xml-stylesheet",
                "type=\"text/xsl\" href=\"" + Url.AbsoluteAction("SitemapXsl", "Default") + "\""),
            new XElement(ns + "urlset",
                new XAttribute(XNamespace.Xmlns + "sitemap", ns),
                new XAttribute(XNamespace.Xmlns + "xhtml", xhtml), 
                nodeList));

        Response.AddHeader("X-Robots-Tag","noindex");
        return Content(sitemap.Declaration+"\r\n"+sitemap, "text/xml");

我们还使用 xsl 样式表来转换站点地图。这有助于浏览器不自动提供像样的格式化程序。请参阅 http://www.autoquoter.com/aq/en/Default/SitemapXsl 了解我们正在使用的样式表。

【讨论】:

  • 这正是我要找的,所以您使用 xls 在浏览器中转换 xml。很好的解决方案,谢谢!
【解决方案2】:

编辑 1:

看来你可能会丢失一些xml特定的头文件:

Check this link out

这也可能是一个关于如何创建 xml 站点地图的有效示例:

Sitemap xml for google Another example
选项1 试试这段代码(取自here):

    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class Sitemap : IHttpHandler
    {
        private const string NAMESPACE = "http://www.sitemaps.org/schemas/sitemap/0.9";

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/xml";
            XmlDocument sitemapDocument = GetSitemapDocument();
            context.Response.Write(sitemapDocument.InnerXml);
        }

        #region Build sitemap document methods
        private XmlDocument GetSitemapDocument()
        {
            XmlDocument sitemapDocument = new XmlDocument();
            sitemapDocument.PreserveWhitespace = true;

            XmlDeclaration xmlDeclaration = 
                sitemapDocument.CreateXmlDeclaration("1.0", "UTF-8", string.Empty);
            sitemapDocument.AppendChild(xmlDeclaration);

            XmlElement urlset = sitemapDocument.CreateElement("urlset", NAMESPACE);
            sitemapDocument.AppendChild(urlset);

            List<SitemapPage> urls = GetSitemapPages();

            foreach (SitemapPage sitemapPage in urls)
            {
                XmlElement url = CreateUrlElement(sitemapDocument, sitemapPage);
                urlset.AppendChild(url);
            }
            return sitemapDocument;
        }

        private XmlElement CreateUrlElement(XmlDocument sitemapDocument, 
            SitemapPage sitemapPage)
        {
            XmlElement url = sitemapDocument.CreateElement("url", NAMESPACE);

            XmlElement loc = CreateElementWithText(sitemapDocument, "loc", 
                sitemapPage.Location);
            url.AppendChild(loc);

            if (sitemapPage.LastModificationDate.HasValue)
            {
                //lastmod must be a string that comforms to the W3C Datetime format
                string lastModValue = sitemapPage.LastModificationDate.Value.ToString(
                    "yyyy'-'MM'-'dd'T'HH':'mm':'ssK");
                XmlElement lastmod = CreateElementWithText(
                    sitemapDocument, "lastmod", lastModValue);
                url.AppendChild(lastmod);
            }

            if (!string.IsNullOrEmpty(sitemapPage.ChangeFrequency))
            {
                XmlElement changefreq = CreateElementWithText(sitemapDocument, 
                    "changefreq", sitemapPage.ChangeFrequency);
                url.AppendChild(changefreq);
            }

            if (sitemapPage.Priority.HasValue)
            {
                XmlElement priority = CreateElementWithText(sitemapDocument,
                    "priority", sitemapPage.Priority.Value.ToString(
                        CultureInfo.CreateSpecificCulture("en-US")));
                url.AppendChild(priority);
            }

            return url;
        }

        private XmlElement CreateElementWithText(
            XmlDocument document, string elementName, string text)
        {
            XmlElement element = document.CreateElement(elementName, NAMESPACE);

            XmlText elementValue = document.CreateTextNode(text);
            element.AppendChild(elementValue);

            return element;
        }
        #endregion

        private List<SitemapPage> GetSitemapPages()
        {
            List<SitemapPage> sitemapPages = new List<SitemapPage>();

            //Example implementation
            sitemapPages.Add(new SitemapPage("http://www.mydomain.com") 
                { ChangeFrequency = "daily", LastModificationDate = DateTime.Now, Priority = 1f });
            sitemapPages.Add(new SitemapPage("http://www.mydomain.com/aPage.aspx") 
                { ChangeFrequency = "daily", LastModificationDate = DateTime.Now, Priority = 0.8f });

            return sitemapPages;
        }

        private class SitemapPage
        {
            public SitemapPage(string location)
            {
                Location = location;
            }

            public string Location { get; private set; }
            public DateTime? LastModificationDate { get; set; }
            public string ChangeFrequency { get; set; }
            public float? Priority { get; set; }
        }

        public bool IsReusable
        {
            get
            {
                return true;
            }
        }
    }

OPTION2:根据 MSDN,这是一个有效的站点地图:sitemap MSDN

检查这个输出:

<siteMap>
  <siteMapNode title="Home" description="Home" url="~/default.aspx">
    <siteMapNode title="Products" description="Our products"
      url="~/Products.aspx">
      <siteMapNode title="Hardware" description="Hardware choices"
        url="~/Hardware.aspx" />
      <siteMapNode title="Software" description="Software choices"
        url="~/Software.aspx" />
    </siteMapNode>
    <siteMapNode title="Services" description="Services we offer"
        url="~/Services.aspx">
        <siteMapNode title="Training" description="Training classes"
          url="~/Training.aspx" />
        <siteMapNode title="Consulting" description="Consulting services" 
          url="~/Consulting.aspx" />
        <siteMapNode title="Support" description="Supports plans" 
          url="~/Support.aspx" />
    </siteMapNode>
  </siteMapNode>
</siteMap>

也许您应该尝试更改您的代码:

public class XmlSitemapResult : ActionResult
{
    private XNamespace nsSitemap = "http://www.sitemaps.org/schemas/sitemap/0.9";
    private XNamespace nsXhtml = "http://www.w3.org/1999/xhtml";

    private IEnumerable<SitemapItem> _items;

    public XmlSitemapResult(IEnumerable<SitemapItem> items)
    {
        _items = items;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        string encoding = context.HttpContext.Response.ContentEncoding.WebName;
        XDocument sitemap = new XDocument(new XDeclaration("1.0", encoding, "yes"),
             new XElement(nsSitemap + "siteMap", new XAttribute(XNamespace.Xmlns + "xhtml", nsXhtml),
                  from item in _items
                  select CreateItemElement(item)
                  )
             );

        context.HttpContext.Response.ContentType = "application/xml";
        context.HttpContext.Response.Charset = encoding;
        context.HttpContext.Response.Flush();
        context.HttpContext.Response.Write(sitemap.Declaration + sitemap.ToString());
    }

    private XElement CreateItemElement(SitemapItem item)
    {
        XElement itemElement = new XElement(nsSitemap + "siteMapNode", new XElement(nsSitemap + "loc", item.Url.ToLower()));

        if (item.LastModified.HasValue)
            itemElement.Add(new XElement(nsSitemap + "lastmod", item.LastModified.Value.ToString("yyyy-MM-dd")));

        if (item.ChangeFrequency.HasValue)
            itemElement.Add(new XElement(nsSitemap + "changefreq", item.ChangeFrequency.Value.ToString().ToLower()));

        if (item.Priority.HasValue)
            itemElement.Add(new XElement(nsSitemap + "priority", item.Priority.Value.ToString(CultureInfo.InvariantCulture)));

        foreach (var alternateLink in item.AlternateLinks)
        {
            itemElement.Add(new XElement(nsXhtml + "link", 
                new XAttribute("rel", "alternate"),
                new XAttribute("hreflang", alternateLink.Language),
                new XAttribute("href", alternateLink.Url)));
        }

        return itemElement;
    }
}

【讨论】:

  • 感谢您的回答。尽管两者都不适用于 xhtml 备用链接。此外,我使用的边图节点直接来自谷歌,所以我想这些是我想要使用的一次。我不知道它们对于搜索引擎是否有任何区别,但如前所述,它们不支持备用链接。我相信那里出了问题。
  • 是的,我都看了,两者都没有使用导致问题的 xhtml 备用链接。如果我不使用 xhtml 标签,它会在我的浏览器中显示为 XML。
  • 我认为问题在于您没有包含命名空间、XML 起始节点和其他强制性 xml 标头内容。检查这个:store.cascadepools.co.uk/feeds/CascadePoolsStore_gs.xml
  • 我会尝试添加这些,我会在完成后回复您。 (今天晚些时候)
  • 我添加了其他标题,但没有帮助。我真的认为这与xhtml有关。 (在您的任何示例中都没有)
猜你喜欢
  • 2013-10-12
  • 2012-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-23
  • 2011-05-13
  • 2014-08-08
  • 1970-01-01
相关资源
最近更新 更多