XML(XAML)とVisualStudioのエディタについて

タグの編集
投稿者 SSD  (社会人) 投稿日時 2023/3/10 17:22:20
WPFを学び始めた者です。
WPFで使用するXAMLについて取り掛かっていた際に躓きました。

以前からXMLを使用することがあったのですが、
名前空間のURIをいまいち理解できていません。

名前空間で指定するURIは何でもいい&URIにスキーマなどのドキュメントはなくてもいい
という説明を見ました。

例えばWPFで最初に生成されるXAMLのWindowには以下の名前空間があります。
x:Class="LoginWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

ここで例えば
x:ABC="abc"
と書くと
「プロパティ"ABC"は"http://schemas.microsoft.com/winfx/2006/xaml"名前空間に存在しません。」
という警告が出てきます。

これが理解できないというか、名前空間の別名は何でもいいのでは?
と思っています。
また、最初の記述
x:Class="LoginWindow"
で警告が出ていないところを見るとClassはxのプロパティとして存在しているのだとは思うのですが、
何が存在していて何が存在していないのかというのはどこでわかるのでしょうか?

ご存じの方いらっしゃいましたらご教示お願い致します。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2023/3/11 17:30:58
> 名前空間のURIをいまいち理解できていません。
「XML 文書」において、
名前空間Ⓐの ABC 要素や XYZ 属性と
名前空間Ⓑの ABC 要素や XYZ 属性とは別物です。

名前空間が指定されていない文書の場合、
<ABC XYZ=""/> というデータが、Ⓐの情報かⒷの情報か区別できなくなります。


ただし、URI 自体に意味があるわけではありません。
それぞれのスキーマを一意に識別できる値になっていればそれで良いので、
="http://www.w3.org/2001/XMLSchema" でも 
="urn:isbn:978-4-88166-220-5" でも
="urn:uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" でも OK です。


> 名前空間で指定するURIは何でもいい&URIにスキーマなどのドキュメントはなくてもいい
> という説明を見ました。
はい、文法的には任意の URI を指定できます(URI は大文字小文字を区別します)。
ただし、何を指定しても良いというわけではありません。

それぞれのスキーマは、ターゲットとしている名前空間がセットで定義されており、
その名前空間と一致する XML 構造が求められます。なので、それに合わせた URI を
それぞれ指定する必要があるということです。

スキーマ定義は外部ファイルになっていることもあれば、
文書型宣言 !DOCTYPE として埋め込まれていることもありますし
解析処理する側(パーサー)にスキーマ情報が保持されていることもあります。


スキーマに合致している XML 文書は「妥当な XML (Valid XML)」と呼ばれますが、
そうでない XML 文書は Well Formed XML (整形式の XML 文書) 扱いです。
スキーマを処理しないパーサーの場合も、Well Formed XML として読み取られます。
もちろん、XML 文法にさえ合致していないものはエラー扱いですけれどね。(Invalid XML)


そして「WPF 文書」では、この XML のルールが XAML のルールへと拡張されています。
XAML の名前空間については下記をご覧ください。
https://learn.microsoft.com/ja-jp/dotnet/desktop/wpf/advanced/xaml-namespaces-and-namespace-mapping-for-wpf-xaml?WT.mc_id=DT-MVP-8907

XAML ファミリーのフレームワークとしては、WPF 以外にも
.NET MAUI や UWP 、古いものだと Xamarin や Silverlight などがあります。


> x:Class="LoginWindow"
> xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
> xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

> ここで例えば
> x:ABC="abc"
> と書くと
> 「プロパティ"ABC"は"http://schemas.microsoft.com/winfx/2006/xaml"名前空間に存在しません。」
> という警告が出てきます。
警告メッセージの通りですよ。
そこで指定した既知の名前空間には、"ABC" という名前のプロパティが定義されていない、ということです。


標準では、"http://schemas.microsoft.com/winfx/2006/xaml" という XML名前空間に対して
x という NCName が別名として付与されている状態ですが、別名は x 以外であっても構いませんし、
同じ名前空間に対して複数の別名を持たせても良いですし、
同じ別名に対して、子要素が親要素とは異なる名前空間を上書きして割り当てても構いません。

すなわち、下記はいずれも適切な WPF 文書です。

<Window さんぷる:Class="MainWindow"
  xmlns:さんぷる="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  Title="Example"
/>


<VisualBasic:Window 中学校:Class="MainWindow"
  xmlns:VisualBasic="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:中学校="http://schemas.microsoft.com/winfx/2006/xaml"
/>


<x:Window
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:y="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:z="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    x:Title="主窓"
    y:Class="MainWindow"
    Width="320"
    z:Height="320">
    <y:Grid xmlns:y="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    </y:Grid>
</x:Window>



> 警告が出ていないところを見るとClassはxのプロパティとして存在しているのだとは思うのですが、
ルート要素にある Page や Window などは、WPF XAML の名前空間のものですが、
x:Class は WPF ではなく、XAML の名前空間に属するメンバーです。
まぁ、本来は x というよりも、"http://schemas.microsoft.com/winfx/2006/xaml" のものなわけですが。


> 何が存在していて何が存在していないのかというのはどこでわかるのでしょうか?
x:Class ディレクティブに関しての情報は、一応このあたり。
https://learn.microsoft.com/ja-jp/dotnet/desktop/xaml-services/xclass-directive?WT.mc_id=DT-MVP-8907

もう少し統括的な資料が必要なら、下記からダウンロードできます。
https://www.microsoft.com/en-us/download/details.aspx?id=19600&44F86079-8679-400C-BFF2-9CA5F2BCBDFC=1
上記のうち、たとえば x:Class ディレクティブに関してであれば、
[MS-XAML]だと、セクション 4.3.1.6 や 5.3.7 、
[MS-XAML-2009,2012,2017] だと、セクション  6.3.1.6 や 7.3.7 あたり。

PDF ではなく Web ベースだとこのあたりですかね。
https://github.com/microsoft/xaml-standard
https://learn.microsoft.com/ja-jp/dotnet/desktop/xaml-services/?WT.mc_id=DT-MVP-8907
https://learn.microsoft.com/ja-jp/dotnet/desktop/wpf/advanced/xaml-in-wpf?WT.mc_id=DT-MVP-8907&view=netframeworkdesktop-4.8
https://learn.microsoft.com/ja-jp/dotnet/desktop/wpf/advanced/wpf-xaml-namescopes?WT.mc_id=DT-MVP-8907


和書だと、 ISBN:978-4797339161 あたりとか。(ちょっと古いか?)

リファレンスとしてではなく、入門的な情報というところなら、このあたりとか。
https://kisuke0303.sakura.ne.jp/blog/?p=340



ちなみに(XAML ではなく)XML エディタ向けの静的なスキーマの幾つかは、 Xml\Schemas\ フォルダーにあります。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2023/3/12 11:07:24
x:Class="namespace.classname"
 XAML オブジェクト ツリーのルートです。
 マークアップとコード ビハインドの間で Partial Class を結合するよう、XAML マークアップのコンパイルを
 設定します。このディレクティブの解釈は XAML プロセッサ依存ですが、CLR 言語規則では下記のルールに従います。
 • 属性値にはネストされた内部クラスは使用できません。
 • クラスの完全修飾名を指定する必要があります (namespace が無い場合は classname のみ指定します)。
 • Page または Application 定義の コード ビハインド ファイルは、プロジェクトの一部として
  含まれているコード ファイルの中に存在する必要があります。
 • コード ビハインド ファイルが C++ の場合も、名前空間の区切りは "::" ではなく "." で指定します。

x:ClassModifier="NotPublic"
 x:Class と共に指定され、そのクラスの XAML のコンパイル動作を
 System.Reflection.TypeAttributes.NotPublic 相当に変更します。省略時は
 System.Reflection.TypeAttributes.Public 相当として扱われます。
 ただしここに記述する文字列は言語依存です。
 • C++/CLI … XAML のコンパイルをサポートするターゲットは存在しません。
 • Visual Basic … "Friend" を指定します。省略時は "Public" として扱われます。
 • C# … "internal" を指定します。省略時は "public" として扱われます。
 なお、x:Class ではネストされた内部クラスがサポートされないため、
 その他のアクセスレベルの制限(C# の private など)は使用されません。
----------
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 Windows Presentation Foundation 名前空間。通常は、デフォルト名前空間へマップされます。
 この名前空間に属する要素や属性は WPF や UWP のクラス ライブラリの項目と対応付けられます。

xmlns="http://schemas.microsoft.com/client/2007"
 Sliverlight 名前空間。
 Sliverlight のサポートは 2021/10/12 に終了しています。

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 XAML 名前空間。通常はエイリアス x でマップされます。
 XAMLのコードを記述するのに必要な要素や属性のための名前空間です。

xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 デザイナー向けの支援機能を提供します。

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ie="http://schemas.microsoft.com/expression/2010/interactions"
 WPF 用の XAML Behaviors 名前空間。
 ユーザーとの対話インターフェイスの振る舞いを提供します。これは旧形式です。

xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
 WPF 用の XAML Behaviors 名前空間。現行形式であり、一つ上で紹介したものを置き換えます。
 下記の参考資料も参照してください。
 https://devblogs.microsoft.com/dotnet/open-sourcing-xaml-behaviors-for-wpf/
 https://elf-mission.net/programming/wpf/wpf-tips/xaml-behaviors-wpf-interactivity/

xmlns:c1="http://schemas.componentone.com/winfx/2006/xaml"
 GrapeCity 社の ComponentOne ブランドのライブラリで使用されています。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2023/3/12 14:52:23
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 マークアップの互換性を扱う名前空間。
 下記の ECMA-376, 5ᵗʰ の Part 3 “Markup Compatibility and Extensibility”で
 XML マークアップ互換性仕様に関するセクションで解説されています。
 https://www.ecma-international.org/publications-and-standards/standards/ecma-376/

mc:Ignorable="prefix1 prefix2 prefixe3 ..."
 XAML マークアップファイルで用いられる XML 記述のうち、要素や属性の前に prefix: として
 付与される名前空間プレフィックス(xmlns:prefix="URI" で指定されたプレフィックス)を指定します。
 複数のプレフィックスが必要な場合は、スペース区切りで指定します。
 ここで指定されたプレフィックスをもつ要素や属性は、それが基になる型を解決できない場合にも
 解析エラーにはせず、単に無視されるようになります。
 これは、将来予約された機能拡張や、プラットフォーム依存のマークアップのために利用できます。

mc:ProcessContent="prefix:Element1 prefix:Element2 ..."
 mc:Ignorable で無視された要素がある場合、XAML プロセッサは、その子コンテンツも既定で無視しますが、
 mc:ProcessContent 属性で指示された要素については、直接の親要素が無視されたとしても、
 次に使用可能な親要素によって、要素内のコンテンツの処理を続行させることができます。
投稿者 SSD  (社会人) 投稿日時 2023/3/17 14:43:04
魔界の仮面弁士さんの解説やご提示いただいたサイト等を見たのですが、
今の私では理解が追い付いておりません...
数日間少しずついじってデータバインディングやMVVMなどはある程度理解できたのですが、
この名前空間だけは理解できず、コピペしてるだけなので全くしっくりきません。

ただ、XAMLでの名前空間の指定はクラスファイルでのImportsに相当するんだなということはぼんやりと感じてきました。
プロジェクトのプロパティ --> 参照設定 と見ていけば参照名が一覧になっています。
これに相当するXAMLの名前空間のURI一覧のようなものはVisualStudioにはないのでしょうか?

マテリアルデザインのライブラリをNuGetで取得しました。
使用方法を調べたところ名前空間で
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
というようにURIを指定すると使用できることはわかりました。(materialDesignの部分はなんでもいい)
このURIを指定すればよいというのはVisualStudioのどこを見ればわかるのでしょうか?

CLR名前空間の参照について以下のようにすればよいという説明を見ました。
xmlns:name="clr-namespace:<CLR名前空間名>;assembly=<アセンブリ名>"
これは感覚的にわかりやすいといいますか、<CLR名前空間名>も<アセンブリ名>も
VisualStudio内で調べることができます。

ただURIはどこを見ればよいのかわかりません。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2023/3/17 15:12:47
> xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
> このURIを指定すればよいというのはVisualStudioのどこを見ればわかるのでしょうか?

NuGet で公開されているものは、Visual Studio の機能の一部では無いので、
VS を見てもわかりません。それぞれのライブラリのドキュメントまたはソースコードを読みましょう。

xmlns で指定すべき URI は、そのアセンブリの XmlnsDefinitionAttribute 属性で指定されます。
https://learn.microsoft.com/ja-jp/dotnet/api/system.windows.markup.xmlnsdefinitionattribute?view=netframework-4.8.1

これは通常、C# なら AssemblyInfo.cs 、Visual Basic なら AssemblyInfo.vb ファイルで
実装されますので、ソースコードが提供されている場合はそれを見て判断できます。
https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/blob/2a38b2c70a5e851bc5b926e0641c1848e719d86b/MaterialDesignThemes.Wpf/Properties/AssemblyInfo.cs


とはいえ、毎回ソースコードを読むのは苦痛でしょうから、普通はドキュメントを探します。
たとえば
https://www.nuget.org/packages/MaterialDesignThemes/
のライブラリであれば、その大元が
https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit
にあることは NuGet ページで分かりますし、README を読めば名前区間の書かれたサンプルも用意されていますね。
https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/blob/master/README.md#-getting-started
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2023/3/17 15:26:25
stackoverflow に同様の質問がありました。回答内容としてはほぼ同じですね。
https://stackoverflow.com/questions/21648903/discovering-the-xmlns-when-adding-a-reference-in-wpf


ついでに、同じ質問を Bing Chat の AI 検索に調べさせてみました。
こちらも「ドキュメントを読む」か「ソースコードの XmlnsDefinition 属性を見る」と回答されていますね。


投稿者 魔界の仮面弁士  (社会人) 投稿日時 2023/3/17 16:48:23
> こちらも「ドキュメントを読む」か「ソースコードの XmlnsDefinition 属性を見る」と回答されていますね。

あ、すみません。よく見るとちょっと違っていた。

AI 回答ではソースコードから読み取るのではなく、
「ライブラリのアセンブリレベル」の定義から確認するように提案されていますね。


たとえばアセンブリの内容を確認するために、ILSpy や dnSpy、ILDasm などを利用できます。

ILDasm.exe なら .NET SDK に含まれているので、特別な準備なしで使えます。
でもちょっと使いにくいので、個人的には ILSpy か dnSpy をおすすめ。

先の MaterialDesignThemes なら、.nuget フォルダー内にダウンロードされた
MaterialDesignThemes.Wpf.dll を読み込ませれば、下図のように URI を確認できます。

アセンブリを読みだすツールは他にもあるので、そこはお好みで。
(Visual Studio からアドインとして呼び出せるものもあります)

投稿者 SSD  (社会人) 投稿日時 2023/3/18 10:22:11
教えていただいた方法で見ることができました。
ありがとうございました。