/ / XElement usuwa węzeł znaleziony przy użyciu LINQ - .net, xml, vb.net, linq, linq-to-xml

XElement usuwa węzeł znaleziony za pomocą LINQ - .net, xml, vb.net, linq, linq-to-xml

Mam obiekt XElement, który został utworzony przez analizę XML z dokumentu programu Word. Chcę tylko znaleźć i usunąć określony węzeł, który próbuję znaleźć za pomocą LINQ.

XML ma kilkaset wierszy, więc nie chcę publikować tutaj całej rzeczy, pokażę tylko pierwsze 20 wierszy:

<w:body xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:p w:rsidR="00CB3A3E" w:rsidP="00257CF7" w:rsidRDefault="008C1E91">
<w:pPr>
<w:pStyle w:val="Heading-Title" />
</w:pPr>
<w:r>
<w:t>References</w:t>
</w:r>
</w:p>
<w:sdt>
<w:sdtPr>
<w:alias w:val="Client" />
<w:tag w:val="ClientName" />
<w:id w:val="-1008363323" />
<w:lock w:val="contentLocked" />
<w:placeholder>
<w:docPart w:val="DefaultPlaceholder_1082065158" />
</w:placeholder>
<w:dataBinding w:xpath="/project[1]/ClientName[3]" w:storeItemID="{1BDA6E50-A0B2-47FF-9929-1F045B6CF8AD}" />
<w:text />

Węzeł, który chcę usunąć, to: <w:t>References</w:t> . Obecnie otrzymuję „Sequence contains no elements" wyjątek. newBody to XElement.

newBody.Descendants.Where(Function(e) e.Name.Equals("<w:t>") AndAlso e.Value.Equals("References")).First().Remove()

Jak powiedziałem, otrzymuję wyjątek opisany powyżej.Czy w ten sposób powinienem próbować dostać się do tego węzła? Czy jest lepszy sposób? Dlaczego moje zapytanie nie uzyskuje określonego węzła? Każda rada, jak to zrobić lepiej, jest bardzo doceniana, wciąż próbuję nauczyć się najlepszych praktyk, jeśli chodzi o przechodzenie przez XML w .net i samym LINQ. Wielkie dzięki!

Odpowiedzi:

1 dla odpowiedzi № 1

Robię trochę zgadywania, ponieważ to jest VB.net i pochodzę z tła C #, ale część LINQ wygląda tak samo. Myślę, że problem leży w Name.Equals("<w:t>") część. Name nie jest ciągiem, ale XName i ma kilka innych właściwości. Najprawdopodobniej musisz się przyjrzeć Name.LocalName.Equals("t"):

.Where(Function(e) e.Name.LocalName.Equals("t")) AndAlso e.Value.Equals("References"))

Jeśli chodzi o drugą część twojego pytania, jeśli typo prostu chcę usunąć jeden węzeł, a następnie nawigacja do tego konkretnego węzła jest najprawdopodobniej o wiele bardziej wydajna niż tworzenie globalnej reguły dokumentu, do której pasuje tylko jeden węzeł. Moje podejście do Twojego problemu wyglądałoby bardziej tak:

newBody.Element("p").Element("r").Element("t").Remove();

0 dla odpowiedzi nr 2

Masz już działające rozwiązanie ignorujące przestrzenie nazw, ale LINQ to XML obsługuje dostęp do elementów w przestrzeni nazw, więc pokażę ci, że masz dwie opcje:

Dim w As XNamespace = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
newBody.Descendants(w + "t").First(Function(t) t.Value = "References").Remove()



" In Imports section
Imports <xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
" In code
newBody...<w:t>.First(Function(t) t.Value = "References").Remove()