1

Linq to XML を使用して XML テキストを解析しています。返された XDocument は、このすべての名前空間を各ノードに追加し、子孫を見つけることを不可能にするか、少なくとも "Placemark" の検索が機能しません。おそらく、kml:Placemark が検索に適合しないためです。

これを単体テストで基本的な XML ファイルを使用してテストしたところ、問題なく動作しました。私は、XML 宣言部分にすべての名前空間が含まれていなかったと推測しています。

すべての名前空間を追加せずに XML テキストを解析するにはどうすればよいですか?

解析:

    XDocument document = XDocument.Parse(text);
    var polygonNodes = document.Descendants("Polygon"); // yields no nodes, even though there are descendants with this.

元のファイル

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
    <name>poly1_philmont.kml</name>
    <Style id="s_ylw-pushpin_hl">
        <IconStyle>
            <scale>1.3</scale>
            <Icon>
                <href>http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png</href>
            </Icon>
            <hotSpot x="20" y="2" xunits="pixels" yunits="pixels"/>
        </IconStyle>
        <LineStyle>
            <color>ff0000aa</color>
        </LineStyle>
        <PolyStyle>
            <color>33ffaa00</color>
        </PolyStyle>
    </Style>
... </kml>

XDocument で解析 (ルート ノード)

<kml:kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
  <kml:Document>
    <kml:name>poly1_philmont.kml</kml:name>
    <kml:Style id="s_ylw-pushpin_hl">
      <kml:IconStyle>
        <kml:scale>1.3</kml:scale>
        <kml:Icon>
          <kml:href>http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png</kml:href>
        </kml:Icon>
        <kml:hotSpot x="20" y="2" xunits="pixels" yunits="pixels" />
      </kml:IconStyle>
      <kml:LineStyle>
        <kml:color>ff0000aa</kml:color>
      </kml:LineStyle>
      <kml:PolyStyle>
        <kml:color>33ffaa00</kml:color>
      </kml:PolyStyle>
    </kml:Style>
...
</kml:kml>
4

2 に答える 2

2

LINQ to XML データ モデルの欠点が発生していると思います。要素または属性名のプレフィックス部分をモデルに格納せず、代わりに単に名前空間宣言属性 (たとえばxmlns="..."and xmlns:pf="...") を格納し、オブジェクトをシリアル化するときにtree をマークアップするために、要素と属性の接頭辞を推測しようとします。あなたのサンプルでは、​​名前空間は2回定義されていますhttp://www.opengis.net/kml/2.2.1回はデフォルトの名前空間として、xmlns="http://www.opengis.net/kml/2.2"1回はプレフィックスkmlxmlns:kml="http://www.opengis.net/kml/2.2"その場合、要素名のプレフィックスを推測しようとする試みが台無しになり、実装が最後の宣言を次のように考慮しているように見えます。

    string xml = @"<foo xmlns=""http://example.com/ns1"" xmlns:pf=""http://example.com/ns1""/>";

    XDocument doc = XDocument.Parse(xml);

    doc.Save(Console.Out);

出力

<pf:foo xmlns="http://example.com/ns1" xmlns:pf="http://example.com/ns1" />

その間

    string xml = @"<foo xmlns:pf=""http://example.com/ns1"" xmlns=""http://example.com/ns1""/>";

    XDocument doc = XDocument.Parse(xml);

    doc.Save(Console.Out);

出力

<foo xmlns:pf="http://example.com/ns1" xmlns="http://example.com/ns1" />

そのため、入力が作成されるときに名前空間宣言の順序を制御しない限り、同じ名前空間に対する 2 つの名前空間宣言を含む入力 XML は、XDocument または XElement との間で往復できない可能性があります。

それにもかかわらず、要素が名前空間にある限り、LINQ to XML でDescendantsorElementsまたはメソッドを使用して要素にアクセスする正しい方法は、と aElementの連結を使用して、 egを構築することです。XNamespacestringXName

XNamespace ns = doc.Root.Namespace;
IEnumerable<XElement> fooElements = doc.Descendants(ns + "foo");
于 2012-08-28T14:34:13.170 に答える
0

これを使って

XNamespace kmlNS = "http://www.opengis.net/kml/2.2";
XDocument document = XDocument.Parse(text);
var polygonNodes = document.Descendants(kmlNS+"Polygon");
于 2012-08-28T12:56:31.220 に答える