Weer gezever met namespaces vrees ik, maar ik heb er helemaal geen behoefte aan om ze hardcoded te gaan definieren als ze in de xml keurignetjes staan. Dit is een stukje van de xml die ik probeer in te lezen:
En mijn C# code:
Veel simpeler kan niet. Ik heb geen behoefte aan uitgebreide validatie; ik hoef alleen maar de nodes te hebben. Kan mij het schelen als er iets tussen zit wat er niet hoort. Ook houdt ik me in m'n code ook niet bezig met namespaces, want ik heb daar helemaal geen controle over, gezien het van een mediawiki-site komt. Lekker simpel, en wat het moet doen is (met een beetje kennis van linq2xml) kraakhelder wat het moet doen.
Toch werkt het niet, want hij kan dat title element niet vinden. Waarom? Geen flauw idee, maar ik lees overal dat je je namespaces hardcoded in je code moet plempen en bij IEDERE node-selectie (althans dat is het geval bij XmlDocument en SelectNodes e.d.) hem eraan moet herinneren welke namespaces en prefixen je ook al weer had gewild. Dat wordt in dit topic beschreven.
Maar mijn XML document heeft gewoon een default namespace, dus prefixen zijn helemaal niet nodig. Daarnaast zou het mijn code onnodig bloaten, zou het uit elkaar klappen als mediawiki besluit 1 letter in de namespace te veranderen (of em weg te halen) en het maakt selecties onnodig complexer en moeilijker leesbaar.
Dus, vond ik een stukje code om alle namespaces uit een document te strippen, maar dat werkt alleen met linq2xml:
En nu kan ik m'n document als volgt inladen:
Valt nog mee dus.
Wat vinden jullie? Zijn er mooiere methodes (vast wel
) of maak ik een grondige denkfout (vast wel
) of heeft iemand hier al een keer een handige workaround voor gevonden die geen linq2xml vereist (want ik gebruik denk ik toch liever XPath)?
XML:
1
2
3
4
5
6
| <mediawiki xmlns="http://www.mediawiki.org/xml/export-0.3/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.3/ http://www.mediawiki.org/xml/export-0.3.xsd" version="0.3" xml:lang="en"> <page> <title>Main Page</title> <id>6</id> </page> </mediawiki> |
En mijn C# code:
C#:
1
2
3
| XmlReader reader = XmlReader.Create(stream, new XmlReaderSettings() { ValidationType = ValidationType.None }); XDocument doc = XDocument.Load(reader); var title = doc.Descendants("title"); |
Veel simpeler kan niet. Ik heb geen behoefte aan uitgebreide validatie; ik hoef alleen maar de nodes te hebben. Kan mij het schelen als er iets tussen zit wat er niet hoort. Ook houdt ik me in m'n code ook niet bezig met namespaces, want ik heb daar helemaal geen controle over, gezien het van een mediawiki-site komt. Lekker simpel, en wat het moet doen is (met een beetje kennis van linq2xml) kraakhelder wat het moet doen.
Toch werkt het niet, want hij kan dat title element niet vinden. Waarom? Geen flauw idee, maar ik lees overal dat je je namespaces hardcoded in je code moet plempen en bij IEDERE node-selectie (althans dat is het geval bij XmlDocument en SelectNodes e.d.) hem eraan moet herinneren welke namespaces en prefixen je ook al weer had gewild. Dat wordt in dit topic beschreven.
Maar mijn XML document heeft gewoon een default namespace, dus prefixen zijn helemaal niet nodig. Daarnaast zou het mijn code onnodig bloaten, zou het uit elkaar klappen als mediawiki besluit 1 letter in de namespace te veranderen (of em weg te halen) en het maakt selecties onnodig complexer en moeilijker leesbaar.
Dus, vond ik een stukje code om alle namespaces uit een document te strippen, maar dat werkt alleen met linq2xml:
C#:
1
2
3
4
5
6
7
8
| public static XElement StripNS(XElement root) { return new XElement( root.Name.LocalName, root.HasElements ? root.Elements().Select(el => StripNS(el)) : (object) root.Value ); } |
En nu kan ik m'n document als volgt inladen:
C#:
1
| XElement doc = StripNS(XDocument.Load(reader).Elements().First()); |
Valt nog mee dus.
Wat vinden jullie? Zijn er mooiere methodes (vast wel
日本!🎌