Come posso estrarre una parte di un grafico di oggetti xaml tramite linq in xml?
-
09-06-2019 - |
Domanda
Ho un oggetto grafico serializzato su xaml.Un esempio approssimativo di ciò che appare è:
<MyObject xmlns.... >
<MyObject.TheCollection>
<PolymorphicObjectOne .../>
<HiImPolymorphic ... />
</MyObject.TheCollection>
</MyObject>
Voglio utilizzare Linq to XML per estrarre gli oggetti serializzati all'interno di TheCollection.
Nota: MyObject
può essere nominato diversamente in fase di esecuzione;Sono interessato a qualsiasi oggetto che implementa la stessa interfaccia, che ha una raccolta pubblica chiamata TheCollection
che contiene tipi di IPolymorphicLol
.
Le uniche cose che so in fase di esecuzione sono la profondità con cui troverò la raccolta e che l'elemento della raccolta si chiama ``*.TheCollection`.Tutto il resto cambierà.
L'xml verrà recuperato da un database utilizzando Linq;se potessi combinare entrambe le query, quindi invece di ottenere l'intero grafico serializzato e quindi estrarre gli oggetti della raccolta, recupererei semplicemente la raccolta, il che sarebbe carino.
Soluzione
Volere,
Non è possibile scoprire se un oggetto implementa qualche interfaccia esaminando XAML.
Con i vincoli dati puoi trovare l'elemento xml che ha un figlio chiamato .
Puoi utilizzare il seguente codice:Restituirà tutti gli elementi aventi un elemento figlio con cui termina il nome .La collezione
static IEnumerable<XElement> FindElement(XElement root)
{
foreach (var element in root.Elements())
{
if (element.Name.LocalName.EndsWith(".TheCollection"))
{
yield return element.Parent;
}
foreach (var subElement in FindElement(element))
{
yield return subElement;
}
}
}
Per assicurarti che l'oggetto rappresentato da questo elemento implementi un'interfaccia devi leggere i metadati dai tuoi assembly.Ti consiglierei di utilizzare il framework Mono.Cecil per analizzare i tipi nei tuoi assembly senza utilizzare la riflessione.
Altri suggerimenti
@aku
Sì, lo so, xaml non include alcuna indicazione sui tipi di base o sulle interfacce.Ma conosco l'interfaccia degli oggetti root e l'interfaccia che contiene la raccolta, in fase di compilazione.
I grafici serializzati vengono archiviati in un database SQL come XML e utilizziamo linq per recuperarli come XElements.Attualmente, insieme alla tua soluzione, ci limitiamo a deserializzare i grafici, scorrerli, estrarre gli oggetti che vogliamo dalla raccolta, rimuovere tutti i riferimenti ad essi dai loro genitori e quindi eliminare.È tutto molto complicato.Speravo in una soluzione a colpo singolo;qualcosa sulla falsariga di un xpath, ma in linea con la nostra query linq to sql che restituisce solo gli elementi che stiamo cercando...