1

xmlドキュメント内には、次のものがあります

  ...  
    <TablixMembers>
       <TablixMember>
          <Group Name="Details" />
       </TablixMember>
     </TablixMembers>
   </TablixMember>
     <TablixHeader Name="MyField3" />
     <TablixHeader Name="MyField2" /> 
 </TablixMembers>
</TablixMember>

フィールド名 ("MyField3、MyField2、...) を持つ各要素を探す for ループがあります。

for (int g = 0; g < remainingtotals; g++)
{
   groupTotals.Reverse();
   ff.Add(new XElement(ns + "TablixHeader"));
   ff.Descendants(ns + "TablixHeader").Last().SetAttributeValue("Name", groupTotals[g]);

   string nName = GenerateUniqueName("Nsted");
   while (ff.Descendants(ns + "TablixHeader").Any(n => (string)n.Attribute("Name") == groupTotals[g]))
   {
     var newnode = ff.Descendants(ns + "TablixHeader").Where(n => (string)n.Attribute("Name") == groupTotals[g]).Single();
     newnode.ReplaceWith(new XElement(tGroupHeader));
   }

groupTotals.Reverse();
} 

このループ内にList<string> groupTotalsは、フィールドの名前を保持する があります。ループにする必要はないかもしれませんwhile(テストのためにこれを追加しました) 特定のフィールドを探すクエリがあります

var newnode = ff.Descendants(ns + "TablixHeader").Where(n => (string)n.Attribute("Name") == groupTotals[g]).Single();
         newnode.ReplaceWith(new XElement(tGroupHeader));

これにより、newnode が次のように設定されます。

<TablixHeader Name="MyField3" xmlns="http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition" />

次の行で、このノードを新しい xml 要素構造に置き換えようとしています

newnode.ReplaceWith(new XElement(tGroupHeader));

tGroupHeader は、選択した属性名の現在の Tablix ノードを挿入して置き換える必要がある大きな xml 要素テンプレートを含むメモリ ストリームです。

このコードを実行すると、ノードは置き換えられません。実際には何も起こりません。ノードにブレークポイントを設定しました。xml 例外はスローされず、そのまま処理されます。メソッドを間違って呼び出しているか、単一のノードを選択したことが原因で要素が置き換えられていないと思います。

また、大きなxml構造の注入が原因である可能性があると考えましたが、次のような単一の要素のみを使用してこれをテストしました:

newnode.ReplaceWith(new XElement(ns + "Size"));// ns is the xml namespace for the schema I am using

これにより、要素が置き換えられることもありませんでした。

私が間違っている可能性があることについて、誰かが洞察を提供できますか?

-乾杯

4

1 に答える 1

0

私は最終的にこれを回避する方法を見つけました。これは最善の方法ではないかもしれませんが、信頼できるものでした。.Descendants()ノードをクエリしようとしたときに確認できた要素は見つかりましたが、更新されませんでした。これは、すべて1つのメソッド内でクエリに基づいて注入および更新しようとしたことが一因だと思いますしかし、それは私が決定できるすべてでした)。

私が使用した回避策は、要素の作成時に要素の xml 構造をナビゲートしようとする代わりに、特定の名前の ID 属性を追加することでした。

ff.Add(new XElement(ns + "TablixMember"));
ff.Descendants(ns + "TablixMember").Last().SetAttributeValue("Name", groupTotals[g]);
ff.Descendants(ns + "TablixMember").Last().SetAttributeValue("ID", groupedItemTotals[g].GroupPosition.ToString());

これにより、次のような XElement が挿入されます。

   <TablixMembers>
      <TablixMember>
        <TablixHeader xmlns="http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition">
         <Size>1in</Size>
            <CellContents>
              <Textbox Name="GroupTotalPPPccc2973356bf4beaa92cb0409b37b8ef" ID="1">
                   <CanGrow>true</CanGrow>
                       <KeepTogether>true</KeepTogether>
<--end snip -->

IDを追加すると、ノードのクエリがはるかに簡単になりました

  var newnode = ff.Descendants(ns + "TablixMember").Where(n => (string)n.Attribute("ID") == groupedItemTotals[g].GroupPosition.ToString()).Single();

ここから、Replace() を使用してノード内の要素を更新できます。ReplaceWith() SetAttribut() など

このスニペットでは、ノードを選択し、すべての子要素を削除してから、新しい構造を挿入しました

newnode.RemoveAll();
newnode.Add(new XElement(tGroupHeader),
new XElement(ns + "KeepWithGroup"));
newnode.Descendants(ns + "TablixHeader").Last().Descendants(ns + "Textbox").Last().SetAttributeValue("Name", nName);

最後に、使用していた現在のスキーマでは ID 属性がサポートされていなかったため、クリーンアップを実行して、サポートされていない属性を削除しました。

report.Descendants(ns + "TablixMember").Where(p => (string)p.Attribute("ID") != null).Attributes("ID").Remove();
report.Descendants(ns + "Textbox").Where(p => (string)p.Attribute("ID") != null).Attributes("ID").Remove();

他の提案やアイデアを見てみたいと思います。

ありがとう

于 2013-08-21T15:49:25.660 に答える