2008-12-16 68 views
10

我一直在尋找一個組件,允許我將任意C#對象傳遞給XSL變換。使用XPath遍歷任意C#對象圖/應用XSL變換

這樣做的天真的方式是使用XmlSerializer對對象圖進行序列化;然而,如果你有一個大的對象圖,就性能而言,這可能會導致問題。諸如循環引用,延遲加載,代理等問題可能會進一步泥濘這裏的水域。

更好的方法是擁有某種實現IXPathNavigable和XPathNavigator的Adapter類。我遇到的一個例子是ObjectXPathNavigator from Byte-Force - 然而,它的大部分關鍵文檔都是用俄語編寫的,而且我最初的測試似乎表明它有一些怪癖和特質。

是否有人知道(a)英文或(b)提供相同或相似功能的任何其他備選方案的相關資源(概述,教程,博客文章等)?

+0

@jammycakes:將剛剛的「穿透曲線與XSLT」是一個有用的答案給你?如果是的話,我會擴展它。 – 2008-12-16 18:15:31

回答

2

聽起來好像你試圖解決的問題是相當有趣的。乍看之下,我建議你自己寫一個XPathNavigator後代的實現 - 只有20多種方法可以寫,而且他們都沒有特別難的簽名。

使用非緩存反射的幼稚實現將會很慢(ish),但可以很好地用作概念證明,並且可以在出現問題時進行更改以提高性能。

但是......

...我想你可能會遇到來自你的方法,而非來自任何實現細節的一些困難。

XML文件(本質上)是元素和屬性的簡單層次結構 - 節點圖中沒有循環(又名循環)。

XPath表達式可以包含運算符「//」,它廣義的意思是搜索到無限深度。 (關於確切的定義,請參見XPath 1.0的第2.5節。)

如果您將這樣的表達式應用於帶有交叉引用(又稱爲對象週期)的對象圖表,那麼運行XPath評估器進入無限循環的風險因爲它試圖遞歸枚舉一個有效的無限圖。

您或許可以通過某種方式跟蹤XPathNavigator中的父節點並在檢測到循環時拋出異常,但我不確定這將是多麼可行。

+0

看到我對Adam Hawkes的迴應。正如我所指出的那樣,這實際上是一個解決的問題 - 我的問題是它的記錄不完整,有誰知道任何文檔/教程/等英文? – jammycakes 2009-11-12 17:07:44

0

由於對象圖可能是循環的,因此您無法制作出基於樹的結構。最好的辦法是用最簡單的組件來表示對象圖:節點和向量。

更具體地說,使每個節點(對象)具有唯一ID的元素(可能由C#的GetHashCode()方法提供?)。引用其他對象(向量)將通過引用對象的ID來處理。

實例類(請注意,我不知道C#,所以我的語法可能有點關閉):

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); 
    } 
} 

然後我們希望xmlOutput的值是這樣的(注意,ID選擇的值是完全人工合成的):

<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

這實際上並不回答我的問題。正如我所說,這個問題已經解決了 - 這只是記錄不完整。如果您的XSLT轉換正在懶惰地評估它們,可能循環的對象圖不一定是問題。 – jammycakes 2009-11-12 17:05:45

6

有標題爲XPath Querying Over Objects with ObjectXPathNavigator(非常)舊MSDN文章實現了一個類似的類(也稱爲ObjectXPathNavigator,有趣的是)。我很久以前使用Visual SourceSafe查詢一些數據,並從更新日誌構建一個RSS源,並且它工作得很好。但是,我沒有對它做XSLT,所以我不確定它是否有效。另外請注意,它是爲Framework 1.0編寫的,因此您可能需要更新它以獲取更多最新的frameoworks。此外,現在可能有更好的方法來做到這一點,但它會給你一個起點(並且文章在解釋它的工作原理方面做了很好的工作)。

+1

沒有看到你可以從提供的鏈接中獲取源代碼甚至是二進制文件。 – jcmcbeth 2014-05-01 18:29:02