Przetwarzam tekst XML przy użyciu Linq to XML. Zwrócony XDocument dodaje całą tę przestrzeń nazw do każdego z moich węzłów i uniemożliwia znalezienie potomków lub przynajmniej moje wyszukiwanie „Placemark” nie działa, najprawdopodobniej dlatego, że kml:Placemark nie pasuje do wyszukiwania.
Kiedy przetestowałem to w teście jednostkowym, z podstawowym plikiem XML, zadziałało dobrze. Zgaduję, że część deklaracji XML nie miała wszystkich przestrzeni nazw.
Jak mogę przeanalizować tekst XML bez dodawania wszystkich przestrzeni nazw?
Rozbiór gramatyczny zdania:
XDocument document = XDocument.Parse(text);
var polygonNodes = document.Descendants("Polygon"); // yields no nodes, even though there are descendants with this.
oryginalny plik
<?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>
Przeanalizowano za pomocą XDocument (węzeł główny)
<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>
2 odpowiedzi
Myślę, że masz problem z modelem danych LINQ to XML, nie przechowuje on części prefiksu elementu lub nazwy atrybutu w swoim modelu, zamiast tego po prostu przechowuje atrybuty deklaracji przestrzeni nazw (np. xmlns="..."
i xmlns:pf="..."
), a następnie podczas serializacji drzewa obiektów w celu oznaczenia, próbuje wywnioskować prefiks dla elementów i atrybutów. W twoim przykładzie przestrzeń nazw http://www.opengis.net/kml/2.2
jest zdefiniowana dwukrotnie, raz jako domyślna przestrzeń nazw z xmlns="http://www.opengis.net/kml/2.2"
, raz z prefiksem kml
(xmlns:kml="http://www.opengis.net/kml/2.2"
). W takim przypadku próba wywnioskowania prefiksu dla nazw elementów jest zepsuta, wygląda na to, że implementacja bierze pod uwagę ostatnią deklarację jako
string xml = @"<foo xmlns=""http://example.com/ns1"" xmlns:pf=""http://example.com/ns1""/>";
XDocument doc = XDocument.Parse(xml);
doc.Save(Console.Out);
Wyjścia
<pf:foo xmlns="http://example.com/ns1" xmlns:pf="http://example.com/ns1" />
Podczas
string xml = @"<foo xmlns:pf=""http://example.com/ns1"" xmlns=""http://example.com/ns1""/>";
XDocument doc = XDocument.Parse(xml);
doc.Save(Console.Out);
Wyjścia
<foo xmlns:pf="http://example.com/ns1" xmlns="http://example.com/ns1" />
Jeśli więc nie kontrolujesz kolejności deklaracji przestrzeni nazw, gdy dane wejściowe są tworzone, wejściowy kod XML z dwiema deklaracjami przestrzeni nazw dla tej samej przestrzeni nazw może nie działać w obie strony z XDocument lub XElement.
Niemniej jednak tak długo, jak elementy znajdują się w przestrzeni nazw, właściwym sposobem z LINQ to XML, aby uzyskać do nich dostęp za pomocą metody Descendants
lub Elements
lub Element
jest użycie konkatenacji XNamespace
z string
do skonstruowania XName
eg
XNamespace ns = doc.Root.Namespace;
IEnumerable<XElement> fooElements = doc.Descendants(ns + "foo");
Użyj tego
XNamespace kmlNS = "http://www.opengis.net/kml/2.2";
XDocument document = XDocument.Parse(text);
var polygonNodes = document.Descendants(kmlNS+"Polygon");
Podobne pytania
Nowe pytania
c#
C # (wymawiane „patrz ostro”) jest językiem programowania wysokiego poziomu, statycznie typowanym, wieloparadygmatowym opracowanym przez firmę Microsoft. Kod C # zwykle jest przeznaczony dla rodziny narzędzi Microsoft .NET i czasów wykonywania, do których należą między innymi .NET Framework, .NET Core i Xamarin. Użyj tego tagu w przypadku pytań dotyczących kodu napisanego w C # lub C # formalnej specyfikacji.