3

わかりましたので、XPATH と C# でこの問題に 1 日中悩まされていました。

次の XML ドキュメントがあります。

<entry xmlns="http://www.w3.org/2005/Atom" xmlns:g="http://base.google.com/ns/1.0"     xmlns:c="http://base.google.com/cns/1.0">
  <item id="362">
    <title>Family Holiday</title>
    <description>a long, wordy description goes here</description>
    <g:id xmlns:g="g">FPS</g:id>
    <g:latitude xmlns:g="g">42.502260</g:latitude>
    <g:longitude xmlns:g="g">1.532850</g:longitude>
  </item>
 </entry>

次に、次のことを行います。

XmlDocument _xmlDocument = new XmlDocument();
_xmlDocument.Load(xmlfile);

XmlNamespaceManager _nameSpaceManager = new XmlNamespaceManager(_xmlDocument.NameTable);
_nameSpaceManager.AddNamespace("RN", "http://www.w3.org/2005/Atom");
_nameSpaceManager.AddNamespace("g", "http://base.google.com/ns/1.0");
_nameSpaceManager.AddNamespace("c", "http://base.google.com/cns/1.0");

XPathNavigator navigator = _xmlDocument.CreateNavigator();

私の問題はこれにあります:

XmlNode nde = _xmlDocument.SelectSingleNode("/RN:entry/RN:item/g:id", _nameSpaceManager);

null を返します - Id ノードではありません。でも、

XmlNode nde = _xmlDocument.SelectSingleNode("/RN:entry/RN:item/RN:title", _nameSpaceManager);

は、タイトル ノードを返します。

私が間違っていることについてのアイデアは大歓迎です!

乾杯サイモン

4

3 に答える 3

3

"/RN:entry/RN:item/g:id"XPath 式が null を返すことを期待します。XPath では、g:名前空間エイリアスは名前空間「http://base.google.com/ns/1.0」を参照しますが、XML ドキュメントでは、g:名前空間エイリアスが参照するように変更されています。id緯度経度要素の名前空間「g」 。

これらの各要素の名前空間エイリアス定義を削除するxmlns:g="g"と、期待どおりに機能するはずです。名前空間エイリアス定義は親 XML 要素から継承されるため、これらのエイリアスは必要ありません (また、正しくありません)。

<entry xmlns="http://www.w3.org/2005/Atom" xmlns:g="http://base.google.com/ns/1.0">
  <item id="362">
    <title>Family Holiday</title>
    <description>a long, wordy description goes here</description>
    <g:id>FPS</g:id>
    <g:latitude>42.502260</g:latitude>
    <g:longitude>1.532850</g:longitude>
  </item>
</entry>

変更されていない XML で動作するようにコードを変更する場合は、代わりにg:、コード内の名前空間宣言の定義を XML 内の定義と一致するように変更します。

_nameSpaceManager.AddNamespace("g", "g");
于 2012-10-15T16:19:01.407 に答える
3

ローカル名前空間の宣言がルート名前空間の定義をオーバーライドしています。

<g:id xmlns:g="g">FPS</g:id>

ここで g:id 属性が名前空間 'g' から来ていることを効果的に言っているのは、ドキュメント要素で定義されている g と同じ名前空間ではありません。

たとえば、XML を次のように変更するとします。

  string xml = @"<entry xmlns=""http://www.w3.org/2005/Atom"" xmlns:g=""http://base.google.com/ns/1.0""     xmlns:c=""http://base.google.com/cns/1.0"">
                  <item id=""362"">
                    <title>Family Holiday</title>
                    <description>a long, wordy description goes here</description>
                    <g:id xmlns:g=""http://base.google.com/ns/1.0"">FPS</g:id>
                    <g:latitude xmlns:g=""http://base.google.com/ns/1.0"">42.502260</g:latitude>
                    <g:longitude xmlns:g=""http://base.google.com/ns/1.0"">1.532850</g:longitude>
                  </item>
                 </entry>";

または単に:

string xml = @"<entry xmlns=""http://www.w3.org/2005/Atom"" xmlns:g=""http://base.google.com/ns/1.0""     xmlns:c=""http://base.google.com/cns/1.0"">
                      <item id=""362"">
                        <title>Family Holiday</title>
                        <description>a long, wordy description goes here</description>
                        <g:id>FPS</g:id>
                        <g:latitude>42.502260</g:latitude>
                        <g:longitude>1.532850</g:longitude>
                      </item>
                     </entry>";

XPath 式は、ローカルの名前空間として機能しg、ドキュメント要素の名前空間の宣言と一致します。g

XML に行き詰まっている場合、他にできることは次のとおりです。

XmlNamespaceManager _nameSpaceManager = new XmlNamespaceManager(_xmlDocument.NameTable);
_nameSpaceManager.AddNamespace("RN", "http://www.w3.org/2005/Atom");
_nameSpaceManager.AddNamespace("g", "g");
_nameSpaceManager.AddNamespace("c", "http://base.google.com/cns/1.0");

XPath が機能するようになります。

XmlDocument、.Net Framework バージョン 4 でテスト済み。

于 2012-10-15T16:20:52.853 に答える
0

行を置き換えるだけです:

_nameSpaceManager.AddNamespace("g", "http://base.google.com/ns/1.0");

_nameSpaceManager.AddNamespace("g", "g");
于 2012-10-15T16:44:27.487 に答える