
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〕という内容が出力されたのでしょうか?
同じオブジェクトなのに、なぜ出力と型がことなるのでしょうか?
ご教授よろしくお願いします。
No.5ベストアンサー
- 回答日時:
> なぜ、Itemメソッドが参照が指すインスタンスがXmlElementクラスのオブジェクトなのに
> 親クラスのオブジェクトとして帰ってくるのかは私にはわかりませんが
戻り値の型が単純にXmlNode型だからですね。
XmlNodeList型がXmlNodeのリストなので,Itemの戻り値をXmlElementとすることができません。
例えば,XmlNode.SelectNodesのXPath式で,/@attrのように属性を指定すればXmlNodeListの中にはXmlAttributeが入りますし,/text()を指定すればXmlTextが入ります。
references)
XmlNodeList.Item メソッド (System.Xml) http://msdn.microsoft.com/ja-jp/library/System.X …
XmlNode.SelectNodes メソッド (String) (System.Xml) http://msdn.microsoft.com/ja-jp/library/hcebdtae
なお,Undocumentedですが,XmlDocument.GetElementsByTagNameの戻り値の型は,
XmlNodeListを継承した,internalなクラスであるSystem.Xml.XmlElementList型になっています。
ただし,Itemの戻り値はXmlNodeのままになっています。
# .NET 4の参照ソースによる
reference)
Microsoft Reference Source Server http://referencesource.microsoft.com/
> GetType().FullNameというのは参照先のインスタンスのクラス名であって
> 変数の型(クラス名)は一切関係ないんですね。ちょっとごっちゃになっていました。
正確に言うと,GetType()の戻り値がインスタンスのTypeだからですね。
Object.GetTypeは「インスタンスの型」を表すSystem.Typeを返します。
今回の場合,nodeObj.GetType() == typeof(XmlElement)は真です。
reference)
Object.GetType メソッド (System) http://msdn.microsoft.com/ja-jp/library/System.O …
No.4
- 回答日時:
> これは,オブジェクトの実際の型に依存し,式中での型に依存しません。
そういうことを言っているわけではなくて、XmlNode.ToString() や
XmlNode.GetType().FullName が、"System.Xml.XmlNode" ではなくて、
"System.Xml.XmlElement" を返すということを言っているのですが。
ちなみに、typeof(XmlNode).FullName は "System.Xml.XmlNode" と完
全限定名を返します。
なお、「完全限定名」と「完全修飾名」は、もとは Fully Qualified
Type Name で、単に日本語訳の違いのようです。MSDN ライブラリの
Object.ToString メソッドの説明は、.NET 3.5 では 「完全限定名」
.NET 4 から「完全修飾名」になってます。一つのページで両方使って
いるものもあります(例:下記 URL)。(笑)
参考URL:http://msdn.microsoft.com/ja-jp/library/yfsftwz6 …
No.3
- 回答日時:
> XmlNode型の変数のnodeObjには実際には本来はXmlElementクラスのインスタンスが
> XmlNodeクラスにアップキャストされてnodeObjという変数に格納されているということでしょうか?
アップキャストといえばアップキャストですね。
キャストの要らない変換の範囲なので,親クラスへの変換はキャストするとはあまり言いませんが……。
より詳しく言うなら,XmlNodeListはその名の通り,XmlNodeのコレクションです。
なので,GetElementsByTagNameで見つかったXmlElementがXmlNode型としてXmlNodeListのコレクションに代入されています。
そして,Itemメソッドの戻り値が既にXmlNode型になっています。
このあたりは,.NET 2.0以降であればIEnuemrable<XmlElement>あたりを返すような実装になったかもしれませんが,
XmlDocumentがそもそも.NET 1.0のジェネリクスのない時代からのものであることもあって,
独自の(型付けされた)コレクション型を用意しているということがあると思います。
# .NET 3.5で追加されたSystem.Xml.Linq.XDocument.Descendantsなどは,IEnumerable<XElement>を返します。
ちなみに……
> MSDN ライブラリには Object.ToString メソッドの既定の実装は、Object
> の型の完全限定名(下記 URL 参照)を返しますとありますが、Object は
> そうでも、XmlNode, XmlElement は違うようです。
MSDNにあるのは,
> Its ToString method returns the object's fully qualified type name.
です。System.Objectの完全修飾名ではなく,「そのオブジェクト」の型の完全修飾名です。
これは,オブジェクトの実際の型に依存し,式中での型に依存しません。
System.Object型の変数にSystem.Xml.XmlElement型のオブジェクトを代入しても,
オブジェクトの型はSystem.Xml.XmlElementであるため,デフォルトの実装はSystem.Xml.XmlElementを返します。
ref) http://msdn.microsoft.com/en-us/library/system.o … http://msdn.microsoft.com/ja-jp/library/system.o …
この回答への補足
回答ありがとうございます。
自分なりにしらべてみましたが
if( nodeObj is XmlElement){
}
とするとどうもtrueが帰ってきているようなのでnodeObjの中にある参照が指し示す
インスタンス自身はあくまでXmlElementクラスのオブジェクトということですね。
なぜ、Itemメソッドが参照が指すインスタンスがXmlElementクラスのオブジェクトなのに
親クラスのオブジェクトとして帰ってくるのかは私にはわかりませんが
GetType().FullNameというのは参照先のインスタンスのクラス名であって
変数の型(クラス名)は一切関係ないんですね。ちょっとごっちゃになっていました。
No.2
- 回答日時:
> Console.WriteLine(nodeObj);
> の箇所の出力で〔XmlElement〕という内容が出力されたのでしょうか?
nodeObj.ToString() で取得できる文字列が "System.Xml.XmlElement" に
なっている(理由は知りませんが Microsoft がそう設定した)という単
純な理由からだと思います。
型名を取得できるわけではありません。
ちなみに、XmlNode.ToString() も XmlElement.ToString() も返される文
字列は同じ "System.Xml.XmlElement" になります。
MSDN ライブラリには Object.ToString メソッドの既定の実装は、Object
の型の完全限定名(下記 URL 参照)を返しますとありますが、Object は
そうでも、XmlNode, XmlElement は違うようです。
参考URL:http://msdn.microsoft.com/ja-jp/library/aa691137 …
No.1
- 回答日時:
System.Object.ToStringはthis.GetType().FullNameを出力します。
そして,XmlElemenetクラスやその先祖クラスはToStringをオーバーライドしません。
このため,System.Xml.XmlElementと出力されます。
この回答への補足
早速の回答ありがとうございます。
すこし、理解がおいつきません。
マニュアルをみるとXML系の継承階層は以下のようです。
System.Object
System.Xml.XmlNode
System.Xml.XmlLinkedNode
System.Xml.XmlElement
XmlNode型の変数のnodeObjには実際には本来はXmlElementクラスのインスタンスが
XmlNodeクラスにアップキャストされてnodeObjという変数に格納されているということでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# Windows Formアプリからコンソールを呼び出して文字を出力させたい 8 2023/05/09 10:53
- C言語・C++・C# C# DatagridviewにExcelシートを反映するとエラーが出る 2 2023/05/06 17:12
- C言語・C++・C# PC画面を録画するプログラムでdllの読み込みエラー 1 2023/04/22 08:31
- Visual Basic(VBA) vbaのエラー対応(実行時エラー7:メモリが不足しています) 4 2023/04/24 00:20
- XML XML同じ名前の要素を自動で集約するツール 1 2022/04/11 09:21
- アプリ Android studio 初心者 Hello Android!しか表示されない 1 2023/08/01 08:47
- AJAX 自作の地図をグーグルマップのようにしたい 3 2022/11/15 11:53
- Java java 入力 3 4 3 出力 ABC DEFG HIJ このようなプログラムの書き方を教えてくだ 2 2022/07/15 14:18
- Java java final 1 2022/06/10 22:49
- その他(IT・Webサービス) 見たことのない形式で日付が表示されているのでそれを解析してほしい 3 2023/01/23 16:53
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルVBA 画像を貼り付ける...
-
VB.netでメソッドからコントロ...
-
サーブレットコンテキストの意...
-
エクセルVBA/SpecialCellsで特...
-
Excel VBA 定数にオブジェクト...
-
[ASP.NET]DropDownListのDB連携...
-
servletからjspへオブジェクト...
-
javaで、、、
-
System.Collections.SortedList
-
C#で親にイベントを投げる方法
-
String型からlong型への変換は...
-
Collections.binarySearchについて
-
PrintFormを使用してのプリント
-
VB2005でADDとINSERTの違いは?
-
Mathパッケージ内でのmodの計算...
-
Vba ListViewの行挿入に関して...
-
ArrayListのデバッグ方法について
-
Calendarクラスでエラーがでる
-
VB.NETでのnothing の意義について
-
JSPでのArrayListの表示につい...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルVBA 画像を貼り付ける...
-
Excel VBA 定数にオブジェクト...
-
VB.netでメソッドからコントロ...
-
サーブレットコンテキストの意...
-
VBAでの[]
-
Vba ListViewの行挿入に関して...
-
C#のクラスで値渡しをする
-
C#で親にイベントを投げる方法
-
VB.NETでのnothing の意義について
-
javaで、、、
-
Javaでブラウザ判定
-
System.Collections.SortedList
-
VB2005でADDとINSERTの違いは?
-
servletからjspへオブジェクト...
-
mkdirsでフォルダが作成されない
-
String型からlong型への変換は...
-
JSPでのArrayListの表示につい...
-
UTF-8のテキストファイルを開く...
-
エクセルVBA/SpecialCellsで特...
-
PrintFormを使用してのプリント
おすすめ情報