質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.84%

  • C#

    6257questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

XMLファイルを読み込み後、特定のIDの要素を書き換える

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 389
退会済みユーザー

退会済みユーザー

前提・実現したいこと

<?xml version="1.0" encoding="utf-8" ?>
<Extension xmlns="">
  <Data
    Id="1A"
    Class=""/>
  <Group
    Id="BGroup">
    <Data
      Id="1B"
      Class=""/>
    <Data
      Id="2B"
      Class=""/>
    <Data
      Id="3B"
      Class=""/>
    <Data
      Id="4B"
      Class=""/>
  </Group>
  <Group
    Id="CGroup">
    <Data
      Id="1C"
      Class=""/>
    <Data
      Id="2C"
      Class=""/>
    <Data
      Id="3C"
      Class=""/>
    <Data
      Id="4C"
      Class=""/>
  </Group>
</Extension>

上記のようなxmlを読込後
Group Id="CGroup"
のData Id="3C"のClassの値を書き換えて保存したいです。
Classだけでなく他の項目がありますが長くなってしまうので省力させてください。

※xmlns=""とか""となっていますがここに書くと長くなったりしていますので省きます。

XmlDocument document = new XmlDocument();
document.Load(FileName);
document.SelectSingleNode(@"/Extension/Group[@Id='CGroup']/Data[@Id='3C']")


とやるとNullがかえってきてしまいます。
どこのPathの書き方が間違っているのでしょうか?
正しく取得できる方法と取得後
Classや他の項目の値を変更して保存する方法を教えていただきたいです。

document.GetElementsByTagName("Group")

とやるとグループは取得できたりするのですがそこから3Cを抜き出す方法が不明です。
List内のInnerxmlを見ると

<Data Id=\"3C\"...> 


とはなっていますが・・・

///////
追記

var nodeList = document.GetElementsByTagName("Group");
foreach (XmlElement list in nodeList)
{
  string id = list.Attributes.GetNamedItem("Id").Value.ToString();
  if (id == "CGroup")
  {
   foreach (XmlElement child in list.ChildNodes)
   {
    string childId = child.Attributes.GetNamedItem("Id").Value.ToString();
        if (childId == "3C")
    {
     child.SetAttribute("Class", "");
       } 
   }
  }
}

document.Save(FileName);
コード雑ですみません。

一応こんな感じで書き換えができるようにはなりました。
遠まわしな書き方だと思っているのですが省略できそうなとこなどありますか?

////////////////////////////////////////////////////////////////////////////////////////////////////////

<?xml version="1.0" encoding="utf-8" ?>
<Extension xmlns="http://会社のURL/Class.xsd">
<Data
Id="1A"
Class=""/>
<Group
Id="CGroup">
<Data
Id="1C"
Class="1CClass"/>
<Data
Id="2C"
Class="2CClass"/>
<Data
Id="3C"
Class="3CClass"/>
<Data
Id="4C"
Class="4CClass"/>
</Group>
</Extension>

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Zuishin

    2017/12/21 18:17

    Plugin はどこにありますか?実際に使っているデータを載せてください。

    キャンセル

  • 退会済みユーザー

    退会済みユーザー

    2017/12/21 19:00

    PluginじゃなくてDataです。間違えてました。

    キャンセル

回答 1

checkベストアンサー

+1

var node = document.SelectSingleNode(@"/Extension/Group[@Id='CGroup']/Data[@Id='3C']/@Class");
node.Value = "NewClass";

これでできました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/22 09:50

    回答ありがとうございます。

    試してみたのですがNullになってしまいます。
    環境は.Net 3.5 visualStudio2015です。

    documentのOuterXmlを見てみると
    <Group Id=\"CGroup\">
    <Data Id=\"3C\" Class=\"3CClass\" />
    どこもこのようになっているのですが原因のひとつでしょうか?

    キャンセル

  • 2017/12/22 09:55

    そもそも XML が挙げられたものと違うならうまくいかないと思います。
    その途中の \ マークは何でしょうか?
    OuterXml に出てくるなら明らかに間違っていると思います。
    どのようにして XML を読み込んでいますか?

    キャンセル

  • 2017/12/22 10:23 編集

    XmlDocument document = new XmlDocument();
    document.Load(FileName);
    で読み込んでいます。
    読み込んでいるXMLファイルは質問に書いてある形式です。
    元のデータの状態は以下のようにしてます。
    <Group
    Id="CGroup">
    <Data
    Id="1C"
    Class="1CClass"/>
    <Data
    Id="2C"
    Class="2CClass"/>
    <Data
    Id="3C"
    Class="3CClass"/>
    <Data
    Id="4C"
    Class="4CClass"/>
    </Group>
    です。

    キャンセル

  • 2017/12/22 10:26

    FileNameはパスとファイル名がつながったものです。

    キャンセル

  • 2017/12/22 10:28

    今度は Extension が消えてませんか?
    「このくらいわかるだろう」と省略したり変更したりすると問題がどこにあるのかわからなくなります。
    質問欄に読み込むファイルの正確な内容を省略せず記載してください。
    もちろん手打ちでなくコピペでお願いします。

    キャンセル

  • 2017/12/22 10:40

    失礼しました。
    質問のほうに追記しました

    キャンセル

  • 2017/12/22 11:27

    追記された XML を input.xml と名付けて実行ファイルと同じディレクトリに置き、次のコードでできることを確認しました。

    var document = new XmlDocument();
    var fileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "input.xml");
    document.Load(fileName);
    var names = new XmlNamespaceManager(document.NameTable);
    names.AddNamespace("xs", "http://会社のURL/Class.xsd");
    var attribute = document.SelectSingleNode(@"//xs:Extension/xs:Group[@Id='CGroup']/xs:Data[@Id='3C']/@Class", names);
    attribute.Value = "NewClass";
    Console.WriteLine(document.OuterXml);

    キャンセル

  • 2017/12/22 11:28

    省略された xmlns が味噌でした。
    次回からは省略せずに書かれることをお勧めします。

    キャンセル

  • 2017/12/22 11:47

    取得できました!!ありがとうございます。
    いろいろとお手数をおかけしました。
    次回からはそのようにしたいと思います。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.84%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C#

    6257questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。