2008-12-16 4 views
10

Ich habe nach einer Komponente gesucht, mit der ich ein beliebiges C# -Objekt an eine XSL-Transformation übergeben kann.Verfolgen eines beliebigen C# -Objektgraphen mit XPath/Anwenden von XSL-Transformationen

Der naive Weg dies zu tun ist, das Objektdiagramm mit einem XmlSerializer zu serialisieren; Wenn Sie jedoch ein großes Objektdiagramm haben, kann dies zu Problemen hinsichtlich der Leistung führen. Probleme wie Zirkelverweise, Lazy Loading, Proxies usw. können die Gewässer hier noch weiter verschmutzen.

Ein besserer Ansatz besteht darin, eine Art Adapter-Klasse zu haben, die IXPathNavigable und XPathNavigator implementiert. Ein solches Beispiel, auf das ich gestoßen bin, ist das ObjectXPathNavigator from Byte-Force - jedoch ist der Großteil der wichtigsten Dokumentation auf Russisch, und meine ersten Tests scheinen darauf hinzuweisen, dass es ein paar Eigenheiten und Eigenarten hat.

Kennt jemand entweder (a) alle Ressourcen (Übersichten, Tutorials, Blog-Posts, etc.) über diese besondere in Englisch oder (b) alle anderen Alternativen, die die gleiche oder eine ähnliche Funktionalität bieten?

+0

@jammycakes: Wird nur „ein Diagramm mit XSLT Verfahrgeschwindigkeit“ Ihnen eine nützliche Antwort sein? Wenn ja, werde ich es erweitern. –

Antwort

2

Klingt, als ob das Problem, das Sie versuchen zu lösen, ziemlich interessant ist.

Auf den ersten Blick würde ich vorschlagen, eine eigene Implementierung eines XPathNavigator Nachkomme Schreiben - nur 20-ungerade Methoden zu schreiben, und keiner von ihnen eine besonders schwierige Signatur haben.

Eine naive Implementierung mit nicht zwischengespeicherten Reflektionen wäre langsam (ish), würde aber als Proof of Concept funktionieren und Sie könnten Änderungen vornehmen, um die Performance zu verbessern, wenn dies ein Problem wurde.

jedoch ...

... Ich glaube, Sie in einige Schwierigkeiten führen kann, die von Ihrem Ansatz stammen, nicht aus jeder Implementierung Detail.

Eine XML-Datei ist (von Natur aus) eine einfache Hierarchie von Elementen und Attributen - im Knotendiagramm gibt es keine Schleifen (auch Zyklen genannt).

Ein XPath-Ausdruck kann den Operator "//" enthalten, was allgemein bedeutet, unbegrenzt zu suchen. (Eine genaue Definition finden Sie in Abschnitt 2.5 von XPath 1.0.)

Wenn Sie einen solchen Ausdruck auf ein Objektdiagramm mit Querverweisen (auch Objektzyklen) angewendet haben, besteht die Gefahr, dass der XPath-Evaluator in eine Endlosschleife geht wie es versucht, einen effektiv unendlichen Graph rekursiv aufzuzählen.

Sie können dieses Problem umgehen, indem Sie die übergeordnete Knoten in Ihrem XPathNavigator irgendwie verfolgen und eine Ausnahme auslösen, wenn eine Schleife erkannt wird, aber ich bin mir nicht sicher, wie rentabel dies sein wird.

+0

Siehe meine Antwort auf Adam Hawkes. Wie ich festgestellt habe, ist dies tatsächlich ein gelöstes Problem - meine Frage ist, dass es schlecht dokumentiert ist, und kennt jemand Dokumentation/Tutorials/etc auf Englisch? – jammycakes

0

Da das Objektdiagramm zyklisch sein kann, können Sie möglicherweise keine baumbasierte Struktur daraus erstellen. Am besten ist es, den Objektgraphen durch seine einfachsten Komponenten darzustellen: Knoten und Vektoren.

Genauer gesagt, machen Sie jeden Knoten (Objekt) ein Element mit einer eindeutigen ID (vielleicht von C# GetHashCode() -Methode bereitgestellt?). Verweise auf andere Objekte (Vektoren) würden durch Verweisen auf die ID des Objekts behandelt werden.

Beispiel Klassen (beachten Sie, dass ich weiß, C# nicht so meine Syntax ein wenig weg sein kann):

public class SomeType { 
    public int myInt { get; set; } 
} 

public class AnotherType { 
    public string myString { get; set; } 
    public SomeType mySomeType { get; set; } 
} 

public class LastType { 
    public SomeType mySomeType { get; set; } 
    public AnotherType myAnotherType { get; set; } 
} 

public class UserTypes{ 
    static void Main() 
    { 
     LastType lt = new LastType(); 
     SomeType st = new SomeType(); 
     AnotherType atype = new AnotherType(); 

     st.myInt = 7; 
     atype.myString = "BOB"; 
     atype.mySomeType = st; 
     lt.mySomeType = st; 
     lt.myAnotherType = atype; 

     string xmlOutput = YourAwesomeFunction(lt); 
    } 
} 

Dann würden wir den Wert von xmloutput erwarten, dass die ID so etwas wie dieses (beachten sein gewählten Werte sind vollständig synthetisch):

<ObjectMap> 
<LastType id="0"> 
    <mySomeType idref="1" /> 
    <myAnotherType idref="2" /> 
</LastType> 

<SomeType id="1"> 
    <myInt>7</myInt> 
</SomeType> 

<AnotherType id="2"> 
    <myString>BOB</myString> 
    <mySomeType idref="1" /> 
</AnotherType> 
</ObjectMap> 
+0

Dies beantwortet meine Frage nicht wirklich. Wie gesagt, das Problem ist gelöst - es ist nur schlecht dokumentiert. Und möglicherweise sind zyklische Objektdiagramme nicht unbedingt ein Problem, wenn Ihre XSLT-Transformationen sie träge auswerten. – jammycakes

6

Es gibt eine ist (sehr) alter MSDN Artikel mit dem Titel XPath Querying Over Objects with ObjectXPathNavigator, die eine ähnliche Klasse implementiert (auch ObjectXPathNavigator interessanter~~POS=TRUNC genannt). Ich habe dieses Alter verwendet, um einige Daten von Visual SourceSafe abzufragen und einen RSS-Feed aus dem Changelog zu erstellen, und es funktionierte ziemlich gut. Ich habe jedoch kein XSLT gemacht, also bin ich mir nicht sicher, ob das funktioniert oder nicht. Beachten Sie auch, dass es für Framework 1.0 geschrieben wurde. Daher müssen Sie es möglicherweise für neuere Frameworks aktualisieren. Vielleicht gibt es auch bessere Möglichkeiten, dies jetzt zu tun, aber es würde Ihnen einen Startpunkt geben (und der Artikel erklärt sehr schön, wie es funktioniert).

+1

Nicht sehen, wo Sie die Quelle oder sogar Binärdateien von dem angegebenen Link erhalten können. – jcmcbeth

+0

https://github.com/AndrewMayorov/ObjectXPathNavigator – user1709408

Verwandte Themen