JSONと相互変換できるXMLの記述
JsonReaderWriterFactoryはどんなJSONでもParseしてXElemnt化できるが、XmlをJSON化するには特定の構造を持っている必要がある。
objectとarrayとその他の単一項目(number, boolean, stringなど)の持ち方が決まっている。
見た目に分かるようなものをwpfで作ってみた。あとで続きを作るかもしれないが原型ができたのでメモ。
<Window x:Class="XMLExperiment.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <TreeView x:Name="tree" Grid.Column="0" ItemsSource="{Binding Root.Children}"> <!--DirectoryViewModel のデータを表示するときに使うテンプレート--> <TreeView.ItemTemplate> <HierarchicalDataTemplate ItemsSource="{Binding Children}"> <TextBlock Text="{Binding Name}"/> </HierarchicalDataTemplate> </TreeView.ItemTemplate> </TreeView> <TextBox x:Name="xml" Grid.Column="1" Text="{Binding Xml}" /> <TextBox x:Name="json" Grid.Column="2" Text="{Binding Json}" /> </Grid> </Window>
namespace XMLExperiment { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); var tree = new Tree(); DataContext = tree; } } }
namespace XMLExperiment { public class Node : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String info) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } } private XElement _e; private ObservableCollection<Node> _children; public Node(XElement e) { _e = e; } public String Name { get { return _e.Name.ToString(); } } public ObservableCollection<Node> Children { get { if (_children == null) { _children = new ObservableCollection<Node>(_e.Elements().Select(e => new Node(e))); } return _children; } } } public class Tree { public Tree() { Json = @"{ ""hoge"":[ 1 ,2 ,3 ,{ ""nazo"": true } ] }"; } private XElement _root; public Node Root { get { return new Node(_root); } } public String Xml { set { } get { return _root.ToString(); } } public String Json { set { using (var reader = JsonReaderWriterFactory.CreateJsonReader(Encoding.Unicode.GetBytes(value), XmlDictionaryReaderQuotas.Max)) { _root=XElement.Load(reader); } } get { using (var ms = new MemoryStream()) using (var writer = JsonReaderWriterFactory.CreateJsonWriter(ms, Encoding.Unicode)) { _root.WriteTo(writer); writer.Flush(); return Encoding.Unicode.GetString(ms.ToArray()); } } } } }
自分はobjectをシリアライズしたりデシリアライズしたいのではなくて動的に組み立ててそれをJSONと相互に変換したいので、
いまいち既存のライブラリとは目的が一致しないのだよな・・・。
泥臭いXElementラッパを作るのが早いかも知れぬ。