C # LINQ xml analisi utilizzando “PreviousNode”

Con un po ‘di aiuto da SO, sono riuscito a mettere insieme la seguente espressione LINQ.

var parentids = xliff.Descendants() .Elements(xmlns + "trans-unit") .Elements(xmlns + "seg-source") .Elements(xmlns + "mrk") .Where(e => e.Attribute("mtype").Value == "seg") .Select(item => (XElement)item.Parent.Parent.PreviousNode) .Where(item => item != null) .Select(item => item.Elements(xmlns + "source") .Where(itema => itema != null) .Select(itemb => itemb.Elements(xmlns + "x") .LastOrDefault() .Attribute("id") .Value.ToString())).ToArray(); 

Quello che fa è che localizza un tag mrk (che ha @mtype="seg" ) e poi sale all’antenato della transunità (.parent.parent) e controlla se la precedente trans-unit ha un bambino trans e se no, restituisce dal figlio di source il @id dell’ultimo elemento x , altrimenti restituisce null (deve restituire null, non può semplicemente non restituire la corrispondenza).

Devo aggiungere che mentre i seguenti esempi hanno solo un nodo precedente senza elementi trans , nella vita reale xml ce ne sono molti altri, quindi devo usare PreviousNode .

Ecco l’XML con cui funziona e restituisce perfettamente "2" :

              Pasadena, California's iconic Colorado Boulevard has been the site of the world-famous Tournament of Roses Parade since it began in 1890.    Pasadena, California's iconic Colorado Boulevard has been the site of the world-famous Tournament of Roses Parade since it began in 1890.     Pasadena, Californiens ikoniske Colorado Boulevard har været stedet for den verdensberømte Rose Bowl-parade siden den begyndte i 1890.       

Il problema è che ho bisogno di risolvere come ultima fase è che c’è un altro tipo di XML che ha la transunità fissa incapsulata all’interno di un altro elemento di group che non è presente nell’altro XML. Quindi qui c’è un altro genitore che salta in alto e ottiene il precedente fratello trans-unit , proprio prima del group .

Sto cercando di creare questo nella stessa espressione LINQ in modo che gestisca entrambi gli scenari.

Infatti se modifico la linea 6 a questo, allora funziona:

 .Select(item => (XElement)item.Parent.Parent.Parent.PreviousNode)  

Ecco l’altro XML che in questo momento genera un’eccezione con il codice precedente, ma dovrebbe restituire "0" :

                    Drugs are robbing our children of their future.   Every 17 seconds a teenager experiments with an illicit drug for the first time.     A drogok megfosztják gyermekeinket a jövőjüktől.   17 másodpercenként egy újabb tizenéves próbálja ki először a kábítószereket.             

Sarò più che riconoscente per qualsiasi aiuto.

Invece di navigare sull’albero XML utilizzando Parent diverse volte in base alla struttura XML, puoi provare a utilizzare Ancestors().Last() per trovare l’antenato di livello più alto denominato "trans-unit" o "group" , quindi passare a il nodo precedente.

Prova a sostituire questa parte:

 .Select(item => (XElement) item.Parent.Parent.PreviousNode) 

con questo :

 .Select(item => (XElement)item.Ancestors() .Last(o => new[]{"trans-unit","group"}.Contains(o.Name.LocalName)) .PreviousNode)