6

xmlファイルを解析する方法は?

<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> 
<sitemap> 
    <loc>link</loc>
    <lastmod>2011-08-17T08:23:17+00:00</lastmod> 
</sitemap> 
<sitemap>
    <loc>link</loc> 
    <lastmod>2011-08-18T08:23:17+00:00</lastmod> 
</sitemap> 
</sitemapindex>

私はXMLを初めて使用します。これを試しましたが、機能していないようです。

        XmlDocument xml = new XmlDocument(); //* create an xml document object. 
        xml.Load("sitemap.xml");
        XmlNodeList xnList = xml.SelectNodes("/sitemapindex/sitemap");
        foreach (XmlNode xn in xnList)
        {
            String loc= xn["loc"].InnerText;
            String lastmod= xn["lastmod"].InnerText;
        }
4

3 に答える 3

14

問題は、sitemapindex要素がデフォルトの名前空間を定義していることです。ノードを選択するときに名前空間を指定する必要があります。指定しないと、ノードが見つかりません。例えば:

XmlDocument xml = new XmlDocument();
xml.Load("sitemap.xml");
XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
manager.AddNamespace("s", "http://www.sitemaps.org/schemas/sitemap/0.9");
XmlNodeList xnList = xml.SelectNodes("/s:sitemapindex/s:sitemap", manager);

通常、を使用するXmlNameSpaceManager場合は、プレフィックスを空の文字列のままにして、その名前空間をデフォルトの名前空間にすることを指定できます。したがって、次のようなことができると思います。

// WON'T WORK
XmlDocument xml = new XmlDocument();
xml.Load("sitemap.xml");
XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
manager.AddNamespace("", "http://www.sitemaps.org/schemas/sitemap/0.9"); //Empty prefix
XmlNodeList xnList = xml.SelectNodes("/sitemapindex/sitemap", manager); //No prefixes in XPath

ただし、そのコードを試してみると、一致するノードが見つからないことがわかります。これは、XPath 1.0(XmlDocumentが実装するもの)では、名前空間が指定されていない場合、デフォルトの名前空間ではなく、常にnull名前空間を使用するためです。したがって、でデフォルトの名前空間を指定するかどうかは関係ありませXmlNamespaceManagerん。とにかく、XPathでは使用されません。公式XPath仕様から関連する段落を引用するには:

ノードテストのQNameは、式コンテキストからの名前空間宣言を使用して、展開された名前に展開されます。これは、開始タグと終了タグの要素タイプ名に対して拡張が行われるのと同じ方法ですが、xmlnsで宣言されたデフォルトの名前空間が使用されない点が異なります。QNameにプレフィックスがない場合、名前空間URIはnullになります(これは同じです)。属性名が展開される方法)。QNameに、式コンテキストに名前空間宣言がないプレフィックスがある場合はエラーになります。

したがって、読み取っている要素が名前空間に属している場合、XPathステートメントに名前空間プレフィックスを含めることを避けられません。ただし、コードに名前空間URIをわざわざ入れたくない場合は、XmlDocumentオブジェクトを使用してルート要素のURIを返すことができます。この場合はこれが必要です。例えば:

XmlDocument xml = new XmlDocument();
xml.Load("sitemap.xml");
XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
manager.AddNamespace("s", xml.DocumentElement.NamespaceURI); //Using xml's properties instead of hard-coded URI
XmlNodeList xnList = xml.SelectNodes("/s:sitemapindex/s:sitemap", manager);
于 2012-07-05T16:16:36.657 に答える
0

サイトマップには、「loc」と「lastmod」の2つのサブノードがあります。アクセスしているノードは「name」と「url」です。そのため、結果が得られません。また、XMLファイルで、最後のサイトマップタグが、対応するxn ["loc"]。InnerTextで適切に閉じられていないことを確認し、目的の結果が得られるかどうかを確認してください。

于 2012-07-05T16:12:40.887 に答える
0

古いXmlDocumentベースのXMLAPIの代わりに、間違いなくLINQtoXMLを使用します。次のコードを使用して、実行しようとしていることを実行できます。値を取得しようとしている要素の名前を「loc」と「lastmod」に変更したことに注意してください。これはサンプルXMLに含まれているためです(「name」と「url」は存在しませんでした)。

XElement element = XElement.Parse(XMLFILE);
        IEnumerable<XElement> list = element.Elements("sitemap");
        foreach (XElement e in list)
        {
            String LOC= e.Element("loc").Value;
            String LASTMOD = e.Element("lastmod").Value;
        }
于 2012-07-05T16:17:33.317 に答える