2010-10-05 61 views
1

問候只是一個列表,從子元素需要從中間

我有一個問題,一個最後期限(我只知道有一些知道點頭那個困境)

背景:我有一個需要以分層的形式存儲數據元素。簡而言之,我的xml是一組規則,它指示圖形繪製引擎根據嚴格的父子關係在圖表上繪製多個系列。即A系列'可以'用它的源數據生成它的父系列等等,或者它可能不是。 我認爲這種方法的強大之處在於,如果我需要刪除一個父系列,刪除父xml節點並且所有依賴/子系列/節點也將被刪除是非常簡單的...魔術就像一個魅力..我幾乎是一個LINQ轉換器。

我有一個圖像來說明 輸出,但顯然我太多的 一個新手,以使圖像的發佈 ..所以想像 繪製基於他們的圖3 4條波浪捲髮線在 以前和一個只是生活的大寂寞..啞圖像上的所有 發佈 規則,但MEH什麼亞該怎麼辦:-(

表示這種關係的XML如下。

<Chart> 
    <Chart_Config AxisClear="False"> 
    <Color>white</Color> 
    <Panels Drawn="True">3</Panels> 
    <SeriesCount>5</SeriesCount> 
    <ChartStyle>Candle</ChartStyle> 
    <DataMode>Daily</DataMode> 
    </Chart_Config> 
    <Series ID="0" Drawn="True"> 
    <Name>0.AAC</Name> 
    <StockCode>AAC</StockCode> 
    <TID>0</TID> 
    <IndID>-1</IndID> 
    <PID>0</PID> 
    <iType>0</iType> 
    <Parent>0</Parent> 
    <Series ID="1" Drawn="True"> 
     <Name>1.SMA</Name> 
     <StockCode>AAC</StockCode> 
     <TID>0.AAC</TID> 
     <IndID>0</IndID> 
     <PID>2</PID> 
     <iType>1</iType> 
     <Parent>0.AAC</Parent> 
     <Parameters> 
     <Param Name="Period" Type="Integer" Min="1" Max="999">10</Param> 
     <Param Name="Color" Type="Color" Min="0" Max="0">0, 0, 192</Param> 
     <Param Name="Transparency" Type="Integer" Min="0" Max="100">0</Param> 
     <Param Name="Width" Type="Integer" Min="1" Max="99">2</Param> 
     </Parameters> 
     <Series ID="2" Drawn="True"> 
     <Name>2.SMA</Name> 
     <StockCode>AAC</StockCode> 
     <TID>1.SMA</TID> 
     <IndID>0</IndID> 
     <PID>0</PID> 
     <iType>1</iType> 
     <Parent>1.SMA</Parent> 
     <Parameters> 
      <Param Name="Period" Type="Integer" Min="1" Max="999">20</Param> 
      <Param Name="Color" Type="Color" Min="0" Max="0">0, 192, 0</Param> 
      <Param Name="Transparency" Type="Integer" Min="0" Max="100">0</Param> 
      <Param Name="Width" Type="Integer" Min="1" Max="99">2</Param> 
     </Parameters> 
     <Series ID="3" Drawn="True"> 
      <Name>3.SMA</Name> 
      <StockCode>AAC</StockCode> 
      <TID>2.SMA</TID> 
      <IndID>0</IndID> 
      <PID>0</PID> 
      <iType>1</iType> 
      <Parent>2.SMA</Parent> 
      <Parameters> 
      <Param Name="Period" Type="Integer" Min="1" Max="999">30</Param> 
      <Param Name="Color" Type="Color" Min="0" Max="0">192, 0, 192</Param> 
      <Param Name="Transparency" Type="Integer" Min="0" Max="100">0</Param> 
      <Param Name="Width" Type="Integer" Min="1" Max="99">2</Param> 
      </Parameters> 
     </Series> 
     </Series> 
    </Series> 
    <Series ID="4" Drawn="True"> 
     <Name>4.SMA</Name> 
     <StockCode>AAC</StockCode> 
     <TID>0.AAC</TID> 
     <IndID>0</IndID> 
     <PID>3</PID> 
     <iType>1</iType> 
     <Parent>0.AAC</Parent> 
     <Parameters> 
     <Param Name="Period" Type="Integer" Min="1" Max="999">40</Param> 
     <Param Name="Color" Type="Color" Min="0" Max="0">192, 0, 0</Param> 
     <Param Name="Transparency" Type="Integer" Min="0" Max="100">0</Param> 
     <Param Name="Width" Type="Integer" Min="1" Max="99">2</Param> 
     </Parameters> 
    </Series> 
    </Series> 
</Chart> 

我發現的問題是,有時我需要更改XML的參數部分中的值,我可以定位並檢索所需的節點..但該節點也包含任何子節點。 例如,如果我檢索名稱爲「系列」且屬性ID爲「2」的XElement,我也會獲得ID = 3的系列條目。

問題A部分:(最後我聽到尖叫聲)....用這個現有的結構,我如何檢索我的一個系列元素而不是它的子元素,因此我可以單獨更新其參數。

和B部分:這是我的格式化XML的正確的方式來實現這個非常有用的父子關係......

乾杯蛇鯊......

附:如果您的答案足以回答,我是否可以打擾您對建議的解決方案如何工作的最低限度描述......我首先使用LINQ to XML,而不是像我希望的那樣直截了當,我仍然認爲在關係數據庫方面。

閱讀完善的帖子後,我琢磨了一下瞧,我的極端暴力方法(不要我們都錯過那些優雅的設計是營銷高管談到獲得銷售的東西)..任何方式。

  /// <summary> 
      /// Updates Parameters in conjunction with the Modify paramteters Dialog 
      /// </summary> 
      /// <param name="Message"></param> 
      private void UpdateIndicatorParameters(IndicatorParamterUpdate Message) 
      { 
       IEnumerable<XElement> result; 
       /// Find the series 
       if (Message.isIndicator) 
       { 
        result = from e in ChartObj.ChartSeriesXMLRules.Descendants() 
          where (e.Name.ToString() == "Series" && e.Attribute("ID").Value == Message.IndicatorID) 
          select e; 
       } 
       else 
       { 
        // not relevant 
       } 



       var NodeOfInterest = result; 

       /// Find Parameter section 
       foreach (var el in result) 
       { 
        NodeOfInterest = el.Elements("Parameters"); 
       } 

/// Find individual paramters     
var result2 = from e in NodeOfInterest.Descendants() 
           where e.Name.ToString() == "Param" 
           select e; 

/// Update required paramter     
foreach (var el in result2) 
       { 
        if (el.Attribute("Name").Value == Message.ParameterName) 
        { 
         el.Value = Message.Value; 

        } 
       } 
      } 

回答

0

如果你把它看作是XML,你總是有後代 - 否則你破壞XML。但只要你看看眼前的小孩的Parameters應該沒問題。如果你將它映射到一個對象模型,你會有一個類似的方法,但是你會忽略Items(或者你所說的任何子成員)。

沒有「正確的方法」,但是,應該就足夠了。在某些情況下你可能想要考慮一個平板模型,但層次似乎適合這個數據OK。通過「扁平」的模式我的意思是你只需:

<Series ID="1" ...>...</Series> 
<Series ID="2" ...>...</Series> 
<Series ID="3" ...>...</Series> 
<Series ID="4" ...>...</Series> 

注意你仍然可以使用現有的<Parent>值來推斷的關聯,而無需其實際佈局的一部分。我不是說要麼是正確的 - 只是說這兩個都是合法的。事實上,目前你有冗餘,因爲你通過結構表達了這種關係;這是罰款直到你犯了一個錯誤,並更新一個,但沒有其他。

+0

TNX馬克,你給我我需要什麼線索在Linq的條件下,我只能聲稱可能是最有力的方法來解決有史以來......(嗯,我可以發佈我的解決方案的一些良好的性質編碼hilarity) – snark 2010-10-07 22:12:06

1

如果您使用XPath,這是簡單的:

/Chart//Series[@ID='4']/Parameters/Param[@Name='Color'] 

會發現只有Parameters元素的具體Series元素的直接孩子,只有指定Param元素立刻這麼Parameters元素。

它會在文檔中查找Series元素的所有位置,如果您要搜索大文檔並且您正在執行此操作,這會有點低效;在這種情況下,它很可能是值得建立一個地圖,如:

var seriesMap = rootXElement 
    .SelectXPathElements("//Series") 
    .ToDictionary(x => x.Attribute("ID").Value); 

然後你就可以得到一個給定的Param元素是這樣的:

string pattern = string.Format("Parameters/Param[@Name='{0}']", name); 
seriesMap[id].SelectXPathElement(pattern); 
+0

這看起來相當優雅..但悲傷地超越我現在。 XPath?系列地圖......當我得到片刻時,我將成爲一個愚蠢的人。 tnx – snark 2010-10-07 22:08:46

+0

'系列圖'很簡單;它是一個'Dictionary ',您可以使用它來查找具有其ID的'Series'元素,而不必通過整個'XDocument'來查找它。 – 2010-10-07 22:23:25