中身が一部しかわかっていないXMLの読み方

このQ&Aのポイント
  • C#でXMLを読み、特定のタグの中身を書き換える処理を実装するための方法について説明します。
  • XMLファイルの中に書き換えたいタグ以外にどんなタグがあるかがわからない場合、再帰処理を使ってタグを探し、見つかったら値を書き換えます。
  • さらにスマートな方法やヒントについても教えてください。
回答を見る
  • ベストアンサー

中身が一部しかわかっていないXMLの読み方

XML例 <A> <B> bbb </B> <C> <D> ddd </D> </C> </A> C#でXMLを読み、特定のタグの中身を書き換える処理を実装しようしています。 ただしXMLファイルの中に書き換えたいタグ以外にどんなタグがあるかがわかっていません。 上記の例の場合、 「<A> - <C> - <D>のdddを書き換えたい」ということはわかっています。 この場合どのように行うのがよいでしょうか? ネットでのソースを参考に書き換えたい値のタグが見つかるまで再帰処理を行い タグが見つかった場合値を書き換えるような処理を書いてみました。 よくあるやり方や、もっとスマートな方法が有りましたらご教授お願いします。 また直接関係なくともヒントとなるようなものでも結構です。 よろしくお願いします。 void test() { XmlDocument document = new XmlDocument(); // ファイルから読み込む document.Load(filePath); readXML(document.DocumentElement); } void readXML(XmlNode node) { // if(node.Name == "D") // 書き換えたい値のタグか判定する //{ // 値を書き換える処理 //} if (node.HasChildNodes) { node = node.FirstChild; while (node != null) { readXML(node); node = node.NextSibling; } } }

  • fenri
  • お礼率50% (11/22)

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

System.Xml.XmlNode.SelectNodesで要素をXPathで指定できますから,これを使います。 ref) http://msdn.microsoft.com/ja-jp/library/hcebdtae(v=vs.110).aspx foreach (var element in document.SelectNodes("/A/C/D").OfType<XmlElement>()) { // element.InnerTextを書き換える } とか, foreach (var textNode in document.SelectNodes("/A/C/D/text()").OfType<XmlText>()) { // textNode.Valueを書き換える } とか。

fenri
質問者

お礼

こうゆうものがあるのですね。 非常に助かりました。 ありがとうございます。

関連するQ&A

  • XMLからデータセットへ

    こんにちは 初めての質問です。 今XML形の文字列があります。 string strXML = @" <dataset1> <table1> <column1>a</column1> <column1>b</column1> <column1>c</column1> <column1>d</column1> <column1>e</column1> <column1>f</column1> </table1> </dataset1>"; この文字列をXMLファイルとして保存します。 XmlDocument xml = new XmlDocument(); xml.LoadXml(strXML); xml.Save(@"C:\test.xml"); 保存したXMLファイルをデータセットで読み込みます。 DataSet ds = new DataSet(); ds.ReadXml(@"C:\test.xml"); 以上の流れでデータセットの作成はできますが、 一回XMLファイルを保存しないといけません。 何とか保存しないで、文字列から直接データセットを生成する方法はありますか? よろしくお願いします。

    • ベストアンサー
    • XML
  • xmlの値を配列に格納したいんですけどエラーがでてしまう。

    <?xml version="1.0" encoding="UTF-8" ?> <Dataroot> <aaa> <bbb> <ccc>値1</ccc> </bbb> <bbb> <ccc>値2</ccc> </bbb> </aaa> </Dataroot> ---------------------------------------------------------------- のようなXML文書がある時<ccc></ccc>の値を取り出す場合 ---------------------------------------------------------------- Imports System Imports System.IO Imports System.Xml public class Sample public shared sub Main() Dim doc as XmlDocument = new XmlDocument() doc.Load("data.xml") 'XML文書の読み込み Dim root as XmlElement = doc.DocumentElement Dim nodeList as XmlNodeList nodeList = root.SelectNodes("/Dataroot/aaa/bbb")'/cccまでやる方が簡単 Dim node as XmlNode Dim ccclist() As String = Nothing for each node in nodeList ccclist(nodeList.Count) = node.SelectSingleNode("ccc").InnerText '内容の取り出し next end sub end class としているのですが ccclist(nodeList.Count) = node.SelectSingleNode("ccc").InnerText '内容の取り出し この行で オブジェクト参照がオブジェクト インスタンスに設定されていません。 とエラーがでて困っています。 これはどのように修正すればよろしいでしょうか? 教えてください。お願いします。

  • XML DOMについて

    JavaScriptでDOMを使用して、xmlhttp.sendで指定のPHPファイルに送信しましたが、 PHP側で値を取得できません。 (PHP Ver.5.3.0) 以下、JavaScript var UserID="abc"; var Password="abc"; var xmlDoc = new ActiveXObject("Microsoft.XMLDom"); xmlDoc.appendChild(xmlDoc.createProcessingInstruction("xml","version=\"1.0\"")); var root = xmlDoc.createElement("xDoc"); xmlDoc.documentElement=root; var node_Item = xmlDoc.createElement("Command"); root.appendChild(node_Item); var node_UserID = xmlDoc.createElement("UserID"); node_UserID.appendChild(xmlDoc.createTextNode(UserID)), node_Item.appendChild(node_UserID); var node_Password = xmlDoc.createElement("Password"); node_Password.appendChild(xmlDoc.createTextNode(MDString(Password))), node_Item.appendChild(node_Password); var node_Sufix = xmlDoc.createElement("Sufix"); node_Sufix.appendChild(xmlDoc.createTextNode(Sufix)), node_Item.appendChild(node_Sufix); var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); xmlhttp.open("post",topURL("main/Log.php"),false); xmlhttp.send(xmlDoc); 以下、Log.php <?php session_start(); $DEBUG_MODE=false; $xmlLogQ=$_SERVER['DOCUMENT_ROOT']."/test/temp/Request.xml"; $xml = new DOMDocument(); $xml->async=false; if (!$DEBUG_MODE) { if ($XML_LOG) { $xml->save($xmlLogQ); } } else { if ($XML_LOG) { $xml->load($xmlLogQ); } } $doc=$xml->documentElement; if ($xml->parseError.errorCode==0) { $xml = $node=$doc->selectSingleNode("Command/UserID"); if (!($node==null)) { $UserID=$node->text; $node=null; } $node=$doc->selectSingleNode("Command/Sufix"); if (!($node==null)) { $Sufix=$node->text; $node=null; } $node=$doc->selectSingleNode("Command/Password"); if (!($node==null)) { $Password=$node->text; $node=null; } } ?> 保存したXML上、<?xml version="1.0"?>以降書き込みできてません。 どの部分がおかしいか不明の為、申し訳ないですがご教授お願いします。

    • ベストアンサー
    • PHP
  • XMLからXML

    こんにちわ。 以下のやり方がわからなく、困っています。 XSLTを使って以下のようなXML→XMLを行いたいのですが。 変更前: <a> <b> <c>abc</c> <d>def</d> </b> </a> 変更後: <b> <c>abc</c> <d>def</d> </b> ようするに、指定したタグ以下のXML構造をそのまま取り出したいのです。 <xsl:template match="/a"> <xsl:apply-templates select="b"/> </xsl:template> だと中身のabc defしか取れません。 <c>とか<d>は、時によって変わる場合、どのようなXSLT を書けばよいのでしょうか? 申し訳ありませんが、わかる方がいれば教えてください。

    • 締切済み
    • XML
  • JavaによるXMLの読み込みについて

    現在、JavaでXMLを読みたく色々なサイト様を参考にさせて頂き プログラムを作成しております。 その結果、下記のようなプログラムで要素名を取得することは出来たのですが、 「属性名」と「属性の値」を読み込み表示することが中々上手くいきません。 どこに何を追加したらよいでしょうか。宜しければ教えて下さい。 -- sample.java -- sample.xml -------------------------------------- import javax.xml.parsers.*; import org.w3c.dom.*; import org.xml.sax.*; import java.io.*; public class sample { public static void main(String[] argv) { sample a = new sample(); a.runner(); } final static String file = "sample.xml"; public void runner() { DocumentBuilderFactory factory; DocumentBuilder builder; Node root; try { factory = DocumentBuilderFactory.newInstance(); builder = factory.newDocumentBuilder(); factory.setIgnoringElementContentWhitespace(true); factory.setIgnoringComments(true); factory.setValidating(true); root = builder.parse(file); showNodes(root, " "); } catch (ParserConfigurationException e0) { System.out.println(e0.getMessage()); } catch (SAXException e1){ System.out.println(e1.getMessage()); } catch (IOException e2) { System.out.println(e2.getMessage()); } } public void showNodes(Node node, String space) { NodeList nodes = node.getChildNodes(); for (int i=0; i<nodes.getLength(); i++) { Node node2 = nodes.item(i); if(!node2.getNodeName().equals("#text")){ System.out.println(space + "<" + node2.getNodeName() + ">"); showNodes(node2, space + " "); } } } }

    • ベストアンサー
    • Java
  • C#のXmlDocumentについて

    C#のXmlDocumentについて質問です。 using System; using System.Xml; using System.Windows; public class XmlNewClass{ public static void Main(String [] args){ XmlDocument xmlObj = new XmlDocument(); xmlObj.Load("./test.xml"); XmlNode nodeObj = xmlObj.GetElementsByTagName("root").Item(0); Console.WriteLine(nodeObj); } } 上記のようなコードがあったとします。 この場合、プロンプトに表示されるないようは 〔System.Xml.XmlElement〕という記述が出力されます。 次に XmlElement elementObj =nodeObj; というコードを追加したとします。 それを実行してみると /****************************************************************** xml.cs(21,26): error CS0266: 型 'System.Xml.XmlNode' を 'System.Xml.XmlElement' に暗黙的に変換できません。明示的な変換が存在します。(cast が不足していないかどうかを確認してください) ***************************************************************************/ というようなエラーがプロンプト上に表示されます。 これはnodeObjがXmlNodeというクラスだということですが (実際GetElementsByTagNameで帰って来るオブジェクトはXmlNodeというクラスだとマニュアルにも記載がありました) なぜ冒頭のコードで Console.WriteLine(nodeObj); の箇所の出力で〔XmlElement〕という内容が出力されたのでしょうか? 同じオブジェクトなのに、なぜ出力と型がことなるのでしょうか? ご教授よろしくお願いします。

  • VBscriptでXMLのファイルから、XPathで指定したデータを読

    VBscriptでXMLのファイルから、XPathで指定したデータを読み込みたいと思っていますが、 XMLファイル中に指定したXPathのタグがない場合、"オブジェクトがありません。" というエラーになってしまいます。 このような場合、どのような処理にすれば良いのでしょうか?親タグ、子タグなどを総当りで、存在するか調べないといけないのでしょうか?以下のようなスクリプトです。 Set xmlDoc = WScript.CreateObject("MSXML2.DOMDocument") With xmlDoc .Async = False .Load("aaaa.xml") xpath01 = "/tag1/tag2/tag3" Set xmlNode = .selectSingleNode(xpath01) MsgBox xmlNode.text End With

  • XMLをJSPで再帰処理を使って処理する方法について

    たびたびすみません、XMLの処理をする上でやり方がわからなくなって しまったので、教えていただきたいのですが。。。 XMLのルートノード以下のものを取得する場合、階層がはっきりしてないとき などは、再帰処理をつかってノードを取得するようにしたいと思っているんですが、JSPでの再帰処理がなかなかうまくできないんです。 再帰処理を行うクラスのメソッドが例えば、 public boolean scanEach(NodeList agNode) { try{ for(int nCnt=0;nCnt<agNode.getLength();nCnt++) { node = agNode.item(nCnt) ; if(node.getNodeType() == Node.ELEMENT_NODE){ out.println("『 "+ node.getNodeName() +"』<br>") ; } if(node.hasChildNodes()) blScanEach(node.getChildNodes()) ; } } catch(Exception except) { except.printStackTrace() ; return false ; } return true ; } と要素ノードを取り出すメソッドがあったら、out.printlnの部分が JSP内での宣言じゃないのでエラーになってしまいます。 JSPで取り出して表示できるようにしたいのですが、なにかいい方法が ないか、教えていただけないでしょうか。 再帰処理を使わなくても、例えばどの階層にあるかわからない<タグ>タグを 検索したりする方法が他にあったら、その方法もおしえていただけると ありがたいのですが。。 何度も申し訳ありません。よろしくお願いします。

    • ベストアンサー
    • XML
  • HasAttributes 的な関数はないでしょう

    お世話になります。 C# WPFで作成しております。 C#でXMLファイルを読み込んで、「view」アトリビュートがあるタグにだけ 処理をしたいと思い下記のソース・xmlを作成しました。 しかしながら、number=1にはviewアトリビュートもあるのですが、 number=2以降はアトリビュートがないのでエラーがでます。 しかしながら、全てのpageタグにviewアトリビュートをつける手間を 増やしたくありません。 viewアトリビュートがあれば、中を見て、if分チェック、タグがなければ、無視をして エラーを出さずに処理を続けるにはどうしたらよいでしょうか? お手数ですがよろしくお願い致します。 --------------C#ソース------------- xmlDocument = new XmlDocument(); xmlDocument.Load(XML文書); //読み込み XmlNodeList nodeList = xmlDocument.SelectNodes("/data/page");//page以下のノードを読み込み int count = nodeList.Count; for (int i = 0; i < count; i++) { if("on"==nodeList[i].Attributes["view"].Value) //viewタグがonなら処理をする {         処理をする } } ----------xml---------- <data> <page number="1" view="on"></page> <page number="2" ></page> <page number="3" ></page> <page number="4" ></page> ------------------------ </data>

  • 2つのxmlファイルを利用したリレーションシップ(?)に関して

    2つのxmlファイルを使用し、リレーションシップ(?)を作成してDataGridViewに表示させようとしているのですがうまくいきません。ご教授お願いいたします。 xmlファイル1: <タグ1> <タグ2 属性21="a1" 属性22="a2"></タグ2> <タグ2 属性21="b1" 属性22="b2"></タグ2> <タグ2 属性21="c1" 属性22="c2"></タグ2> </タグ1> xmlファイル2: <タグ1> <タグ2 属性21="a1" 属性22="d2"></タグ2> <タグ2 属性21="b1" 属性22="e2"></タグ2> <タグ2 属性21="c1" 属性22="f2"></タグ2> </タグ1> 表示させたい内容: | d2 | a2 | | e2 | b2 | | f2 | c2 |