0

xml ファイル (実際には .rdlc レポート ファイル) を変更し、多くの子ノードを持ついくつかのノードを追加する必要があります (これらの子ノードにも子ノードがあります)。実際には、次のようにほとんど同じ構造です。

           <TablixRow>
            <Height>0.23622in</Height>
            <TablixCells>
              <TablixCell>
                <CellContents>
                  <Textbox Name="Textbox1">
                    <CanGrow>true</CanGrow>
                    <KeepTogether>true</KeepTogether>
                    <Paragraphs>
                      <Paragraph>
                        <TextRuns>
                          <TextRun>
                            <Value/>
                            <Style/>
                          </TextRun>
                        </TextRuns>
                        <Style/>
                      </Paragraph>
                    </Paragraphs>
                    <rd:DefaultName>Textbox1</rd:DefaultName>
                    <Style>
                      <Border>
                        <Style>None</Style>
                      </Border>
                      <PaddingLeft>2pt</PaddingLeft>
                      <PaddingRight>2pt</PaddingRight>
                      <PaddingTop>2pt</PaddingTop>
                      <PaddingBottom>2pt</PaddingBottom>
                    </Style>
                  </Textbox>
                </CellContents>
              </TablixCell>
              <TablixCell>
                <CellContents>
                  <Textbox Name="Textbox5">
                    <CanGrow>true</CanGrow>
                    <KeepTogether>true</KeepTogether>
                    <Paragraphs>
                      <Paragraph>
                        <TextRuns>
                          <TextRun>
                            <Value/>
                            <Style/>
                          </TextRun>
                        </TextRuns>
                        <Style/>
                      </Paragraph>
                    </Paragraphs>
                    <rd:DefaultName>Textbox5</rd:DefaultName>
                    <Style>
                      <Border>
                        <Style>None</Style>
                      </Border>
                      <PaddingLeft>2pt</PaddingLeft>
                      <PaddingRight>2pt</PaddingRight>
                      <PaddingTop>2pt</PaddingTop>
                      <PaddingBottom>2pt</PaddingBottom>
                    </Style>
                  </Textbox>
                </CellContents>
              </TablixCell>
            </TablixCells>
          </TablixRow>

それで、それを行う最も簡単な方法は何ですか?通常は、XmlNode といくつかの XmlAttribute オブジェクトを作成し、それらの属性をノードにアタッチし、同じ方法で子ノードを作成し、最後に各子ノードをその親に追加します。言うまでもなく、サンプル ノードを処理するのは面倒です。それを行う簡単な方法はありますか?XmlDocument クラスと同様に、関数 LoadXml (xml を文字列として) があり、これは文字列を xml ファイル全体として受け取り、構造を構築します。XmlNode オブジェクトを構築する同様の方法はありますか? そのため、ノードを表す文字列全体を提供するだけでよく、値を変更する必要がある子ノードに移動します。ありがとう!

更新: VB.NET を使用しています。また、XElement を使用する場合、名前空間に 1 つの問題があります。このリンク XName Classでは、C# ではオーバーライドされた add 演算子を使用して要素と NS を結合することをお勧めしますが、VB では上部で Import を使用することをお勧めします (モジュールの外側の例では、それも必要だと思います)。クラスで動作します)、すべてがこの NS を自動的に使用します。しかし、そうではありません。たとえば、私が与える場合

             Dim para As XElement = _
                <ReportParameter Name="HasErr">
                    <DataType>Boolean</DataType>
                    <DefaultValue>
                        <Values>
                            <Value>False</Value>
                        </Values>
                    </DefaultValue>
                    <Prompt>ReportParameter1</Prompt>
                </ReportParameter>

指定した(およびデフォルトとして記載されている)NSがそこに自動的にアタッチされます。しかし、xml が xml を表す同じ文字列である XElement.Parse(xml As String) を使用すると、この NS はまったく追加されず、最終的に空の NS が使用されます (XElement.Parse を使用する理由)。解析は、 & MY_TYPE_NAME & などのカスタマイズされたパラメーター値をそこに提供したいということです)。2 番目の問題は、@JohnD のコードを使用する場合です。

xdoc.Root.Elements("ReportParameters").FirstOrDefault()

これは、宣言されたデフォルトの NS も使用すると想定し、何も返しません。つまり、空の名前空間内を検索しますが、実際には私が言及した NS 内にあります。

それが、使用する前に名前空間を指定できる XName クラスのコンストラクターがないように MS が作成した理由であることを誰もが知っていますか? 暗黙の変換は 1 つしかないため、要素名を表す文字列が指定された場合

xdoc.Root.Elements("ReportParameters")

Elements の検索にインデックスを付けるために、1 つの XName オブジェクトを暗黙的に生成します。しかし、それは本当に不器用です。

最新の更新: 更新で最初の問題を解決する解決策を見つけました。現在、XML リテラルを使用して XElement を作成しており、その中で式を使用することができます。したがって、次のようになります。

 Dim paraDefNode As XElement = _
                <ReportParameter Name=<%= para.Value %>>
                    <DataType>String</DataType>
                    <DefaultValue>
                        <Values>
                            <Value>False</Value>
                        </Values>
                    </DefaultValue>
                    <Prompt>ReportParameter1</Prompt>
                </ReportParameter>

指定した NS が追加されます。(私が言ったように、XElement.Parse(string)はそれを追加しません)これで、正しいノードを構築できます。2 番目の問題については、まだわかりません。正しい NS を検索しないため、要素名を使用してターゲット ノードに移動できません。

とにかく @JohnD の投稿を回答としてマークします。彼は LINQ to XML の使用を提案したからです。

4

1 に答える 1

3

.NET 4 を使用できる場合は、.NET を参照することをお勧めしXDocumentます。ドキュメントに要素を追加する例を次に示します。

http://msdn.microsoft.com/en-us/library/system.xml.linq.xdocument.add.aspx

XDocument.Parse文字列からドキュメントを初期化するか、ファイルから初期化するために使用できXDocument.Loadます (他のオーバーロードもあります)。

次に、挿入する要素に移動して、XElement.Add()を実行できます。

XML 要素を別の XDocument に配置するサンプル コードを次に示します。ターゲット XDcoument の最初の「Elem」ノードに XML を追加しているだけですが、コードを微調整して複数回追加することもできます...

        public static void Main()
        {

            var xelementToAdd = XElement.Parse(@"
                <TablixRow>
                    <Height>0.23622in</Height>
                    <TablixCells>
                      <TablixCell>
                        <CellContents>
                          <Textbox Name='Textbox1'>
                            <CanGrow>true</CanGrow>
                            <KeepTogether>true</KeepTogether>
                            <Paragraphs>
                              <Paragraph>
                                <TextRuns>
                                  <TextRun>
                                    <Value/>
                                    <Style/>
                                  </TextRun>
                                </TextRuns>
                                <Style/>
                              </Paragraph>
                            </Paragraphs>
                            <DefaultName>Textbox1</DefaultName>
                            <Style>
                              <Border>
                                <Style>None</Style>
                              </Border>
                              <PaddingLeft>2pt</PaddingLeft>
                              <PaddingRight>2pt</PaddingRight>
                              <PaddingTop>2pt</PaddingTop>
                              <PaddingBottom>2pt</PaddingBottom>
                            </Style>
                          </Textbox>
                        </CellContents>
                      </TablixCell>
                      <TablixCell>
                        <CellContents>
                          <Textbox Name='Textbox5'>
                            <CanGrow>true</CanGrow>
                            <KeepTogether>true</KeepTogether>
                            <Paragraphs>
                              <Paragraph>
                                <TextRuns>
                                  <TextRun>
                                    <Value/>
                                    <Style/>
                                  </TextRun>
                                </TextRuns>
                                <Style/>
                              </Paragraph>
                            </Paragraphs>
                            <DefaultName>Textbox5</DefaultName>
                            <Style>
                              <Border>
                                <Style>None</Style>
                              </Border>
                              <PaddingLeft>2pt</PaddingLeft>
                              <PaddingRight>2pt</PaddingRight>
                              <PaddingTop>2pt</PaddingTop>
                              <PaddingBottom>2pt</PaddingBottom>
                            </Style>
                          </Textbox>
                        </CellContents>
                      </TablixCell>
                    </TablixCells>
                  </TablixRow>");

            // you might use XDocument.Load() here instead of Parse()
            var xdoc = XDocument.Parse(@"
<Report xmlns='http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition' 
        xmlns:rd='http://schemas.microsoft.com/SQLServer/reporting/reportdesigner'
        xmlns:msxsl='urn:schemas-microsoft-com:xslt'
        xmlns:xs='http://www.w3.org/2001/XMLSchema' 
        xmlns:msdata='urn:schemas-microsoft-com:xml-msdata'>
    <rd:DrawGrid>true</rd:DrawGrid>
    <ReportParameters></ReportParameters>
</Report>
            ");

            XNamespace ns1 = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition";
            XNamespace ns2 = "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner";
            XNamespace ns3 = "urn:schemas-microsoft-com:xslt";
            XNamespace ns4 = "http://www.w3.org/2001/XMLSchema";
            XNamespace ns5 = "urn:schemas-microsoft-com:xml-msdata";

            var e = xdoc.Root.Elements(ns1 + "ReportParameters")
                .FirstOrDefault();

            e.Add(xelementToAdd);
            xdoc.Save(@"c:\temp\foo2.xml");
        }

そして、それが価値があるために、サンプル XML を微調整して名前空間プレフィックスを削除し (名前空間は質問とは別の問題です)、二重引用符を単一引用符に置き換えました (それ以外の場合、XML は同等です)。

更新: はい、名前空間の問題が発生しています。要素には のような接頭辞があり<ReportParameters>ませんが<rd:DrawGrid>、デフォルトの名前空間を使用しているため、指定する必要があります。更新されたサンプルを見てください。これで、必要なことが実行されるはずです。お役に立てれば!

于 2011-11-03T11:02:19.700 に答える