Answered by:
XML view in WPF

Question
-
I would like to view an XML content in a WPF window. Can you recommend me a WPF control, which is able to show an XML in formatted view?
Thank you,
RobertMonday, June 30, 2008 12:16 PM
Answers
-
This might be closer to what you want:
<Window x:Class="XPathVisualizer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xmlstack="clr-namespace:System.Xml;assembly=System.Xml"
Title="XPath Visualizer">
<Window.Resources>
<SolidColorBrush Color="Blue" x:Key="xmlValueBrush"/>
<SolidColorBrush Color="Red" x:Key="xmAttributeBrush"/>
<SolidColorBrush Color="DarkMagenta" x:Key="xmlTagBrush"/>
<SolidColorBrush Color="Blue" x:Key="xmlMarkBrush"/>
<DataTemplate x:Key="attributeTemplate">
<StackPanel Orientation="Horizontal" Margin="3,0,0,0" HorizontalAlignment="Center">
<TextBlock Text="{Binding Path=Name}" Foreground="{StaticResource xmAttributeBrush}"/>
<TextBlock Text="="" Foreground="{StaticResource xmlMarkBrush}"/>
<TextBlock Text="{Binding Path=Value}" Foreground="{StaticResource xmlValueBrush}"/>
<TextBlock Text=""" Foreground="{StaticResource xmlMarkBrush}"/>
</StackPanel>
</DataTemplate>
<HierarchicalDataTemplate x:Key="treeViewTemplate" ItemsSource="{Binding XPath=child::node()}">
<StackPanel Orientation="Horizontal" Margin="3,0,0,0" HorizontalAlignment="Center">
<TextBlock Text="<" HorizontalAlignment="Center" Foreground="{StaticResource xmlMarkBrush}" x:Name="startTag"/>
<TextBlock
Text="{Binding Path=Name}"
Margin="0"
HorizontalAlignment="Center"
x:Name="xmlTag"
Foreground="{StaticResource xmlTagBrush}"/>
<ItemsControl
ItemTemplate="{StaticResource attributeTemplate}"
ItemsSource="{Binding Path=Attributes}"
HorizontalAlignment="Center">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<TextBlock Text=">" HorizontalAlignment="Center" Foreground="{StaticResource xmlMarkBrush}" x:Name="endTag"/>
</StackPanel>
<HierarchicalDataTemplate.Triggers>
<DataTrigger Binding="{Binding NodeType}">
<DataTrigger.Value>
<xmlstack:XmlNodeType>Text</xmlstack:XmlNodeType>
</DataTrigger.Value>
<Setter Property="Text" Value="{Binding InnerText}" TargetName="xmlTag"/>
<Setter Property="Foreground" Value="Black" TargetName="xmlTag"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="startTag"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="endTag"/>
</DataTrigger>
<DataTrigger Binding="{Binding HasChildNodes}" Value="False">
<Setter Property="Text" Value="/>" TargetName="endTag"/>
</DataTrigger>
</HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox Name="xmlPathTextBox" Grid.Row="0" Grid.Column="0" Margin="3"/>
<Button Margin="3" Content="Browse..." Click="BrowseXmlFile" Grid.Row="0" Grid.Column="1"/>
<TreeView Grid.Row="2" Grid.ColumnSpan="2" Name="xmlTree" ItemTemplate="{StaticResource treeViewTemplate}">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="True"/>
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
</Grid>
</Window>
private void BrowseXmlFile(Object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
dlg.CheckFileExists = true;
dlg.Filter = "xml files (*.xml)|*.xml|all files(*.*)|*.*";
dlg.Multiselect = false;
if (dlg.ShowDialog() == true)
{
try
{
XmlDocument doc = new XmlDocument();
doc.Load(dlg.FileName);
XmlDataProvider provider = new XmlDataProvider();
provider.Document = doc;
Binding binding = new Binding();
binding.Source = provider;
binding.XPath = "child::node()";
xmlTree.SetBinding(TreeView.ItemsSourceProperty, binding);
}
catch (XmlException)
{
MessageBox.Show("Xml is invalid");
}
}
}
For how to include the end XML tag, I leave that for your own exercise:)
Hope this helps
- Marked as answer by Marco Zhou Friday, July 4, 2008 10:27 AM
Friday, July 4, 2008 4:09 AM
All replies
-
Here is an example of using TreeView to visualize the XML with formatting:
<Window x:Class="XPathVisualizer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="XPath Visualizer"
>
<Window.Resources>
<SolidColorBrush Color="Blue" x:Key="xmlValueBrush"/>
<SolidColorBrush Color="Red" x:Key="xmAttributeBrush"/>
<SolidColorBrush Color="DarkMagenta" x:Key="xmlTagBrush"/>
<SolidColorBrush Color="Blue" x:Key="xmlMarkBrush"/>
<Style TargetType="{x:Type ListBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate x:Key="attributeTemplate">
<StackPanel Orientation="Horizontal" Margin="3,0,0,0" HorizontalAlignment="Center">
<TextBlock Text="{Binding Path=Name}" Foreground="{StaticResource xmAttributeBrush}"/>
<TextBlock Text="="" Foreground="{StaticResource xmlMarkBrush}"/>
<TextBlock Text="{Binding Path=Value}" Foreground="{StaticResource xmlValueBrush}"/>
<TextBlock Text=""" Foreground="{StaticResource xmlMarkBrush}"/>
</StackPanel>
</DataTemplate>
<HierarchicalDataTemplate x:Key="treeViewTemplate" ItemsSource="{Binding XPath=child::*}">
<StackPanel Orientation="Horizontal" Margin="3,0,0,0" HorizontalAlignment="Center">
<TextBlock Text="<" HorizontalAlignment="Center" Foreground="{StaticResource xmlMarkBrush}"/>
<TextBlock Text="{Binding Path=Name}" Margin="0" HorizontalAlignment="Center" Foreground="{StaticResource xmlTagBrush}"/>
<ListBox
ItemTemplate="{StaticResource attributeTemplate}"
ItemsSource="{Binding Path=Attributes}"
HorizontalAlignment="Center">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal" IsItemsHost="True"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
<TextBlock Text=">" HorizontalAlignment="Center" Foreground="{StaticResource xmlMarkBrush}"/>
</StackPanel>
</HierarchicalDataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox Name="xmlPathTextBox" Grid.Row="0" Grid.Column="0" Margin="3"/>
<Button Margin="3" Content="Browse..." Click="BrowseXmlFile" Grid.Row="0" Grid.Column="1"/>
<TreeView Grid.Row="2" Grid.ColumnSpan="2" Name="xmlTree" ItemTemplate="{StaticResource treeViewTemplate}"/>
</Grid>
</Window>
private void BrowseXmlFile(Object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
dlg.CheckFileExists = true;
dlg.Filter = "xml files (*.xml)|*.xml|all files(*.*)|*.*";
dlg.Multiselect = false;
if (dlg.ShowDialog() == true)
{
try
{
XmlDocument doc = new XmlDocument();
doc.Load(dlg.FileName);
XmlDataProvider provider = new XmlDataProvider();
provider.Document = doc;
Binding binding = new Binding();
binding.Source = provider;
binding.XPath = "child::*";
xmlTree.SetBinding(TreeView.ItemsSourceProperty, binding);
}
catch (XmlException)
{
MessageBox.Show("Xml is invalid");
}
}
}
Hope this helps
Wednesday, July 2, 2008 4:41 AM -
Hi,
the idea to fill a tree view is very good. I only miss the display of element values such as <Name>Test</Name>. I only see <Name> without any value. Can you reproduce it?
Thank you,
RobertWednesday, July 2, 2008 8:30 AM -
This might be closer to what you want:
<Window x:Class="XPathVisualizer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xmlstack="clr-namespace:System.Xml;assembly=System.Xml"
Title="XPath Visualizer">
<Window.Resources>
<SolidColorBrush Color="Blue" x:Key="xmlValueBrush"/>
<SolidColorBrush Color="Red" x:Key="xmAttributeBrush"/>
<SolidColorBrush Color="DarkMagenta" x:Key="xmlTagBrush"/>
<SolidColorBrush Color="Blue" x:Key="xmlMarkBrush"/>
<DataTemplate x:Key="attributeTemplate">
<StackPanel Orientation="Horizontal" Margin="3,0,0,0" HorizontalAlignment="Center">
<TextBlock Text="{Binding Path=Name}" Foreground="{StaticResource xmAttributeBrush}"/>
<TextBlock Text="="" Foreground="{StaticResource xmlMarkBrush}"/>
<TextBlock Text="{Binding Path=Value}" Foreground="{StaticResource xmlValueBrush}"/>
<TextBlock Text=""" Foreground="{StaticResource xmlMarkBrush}"/>
</StackPanel>
</DataTemplate>
<HierarchicalDataTemplate x:Key="treeViewTemplate" ItemsSource="{Binding XPath=child::node()}">
<StackPanel Orientation="Horizontal" Margin="3,0,0,0" HorizontalAlignment="Center">
<TextBlock Text="<" HorizontalAlignment="Center" Foreground="{StaticResource xmlMarkBrush}" x:Name="startTag"/>
<TextBlock
Text="{Binding Path=Name}"
Margin="0"
HorizontalAlignment="Center"
x:Name="xmlTag"
Foreground="{StaticResource xmlTagBrush}"/>
<ItemsControl
ItemTemplate="{StaticResource attributeTemplate}"
ItemsSource="{Binding Path=Attributes}"
HorizontalAlignment="Center">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<TextBlock Text=">" HorizontalAlignment="Center" Foreground="{StaticResource xmlMarkBrush}" x:Name="endTag"/>
</StackPanel>
<HierarchicalDataTemplate.Triggers>
<DataTrigger Binding="{Binding NodeType}">
<DataTrigger.Value>
<xmlstack:XmlNodeType>Text</xmlstack:XmlNodeType>
</DataTrigger.Value>
<Setter Property="Text" Value="{Binding InnerText}" TargetName="xmlTag"/>
<Setter Property="Foreground" Value="Black" TargetName="xmlTag"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="startTag"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="endTag"/>
</DataTrigger>
<DataTrigger Binding="{Binding HasChildNodes}" Value="False">
<Setter Property="Text" Value="/>" TargetName="endTag"/>
</DataTrigger>
</HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox Name="xmlPathTextBox" Grid.Row="0" Grid.Column="0" Margin="3"/>
<Button Margin="3" Content="Browse..." Click="BrowseXmlFile" Grid.Row="0" Grid.Column="1"/>
<TreeView Grid.Row="2" Grid.ColumnSpan="2" Name="xmlTree" ItemTemplate="{StaticResource treeViewTemplate}">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="True"/>
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
</Grid>
</Window>
private void BrowseXmlFile(Object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
dlg.CheckFileExists = true;
dlg.Filter = "xml files (*.xml)|*.xml|all files(*.*)|*.*";
dlg.Multiselect = false;
if (dlg.ShowDialog() == true)
{
try
{
XmlDocument doc = new XmlDocument();
doc.Load(dlg.FileName);
XmlDataProvider provider = new XmlDataProvider();
provider.Document = doc;
Binding binding = new Binding();
binding.Source = provider;
binding.XPath = "child::node()";
xmlTree.SetBinding(TreeView.ItemsSourceProperty, binding);
}
catch (XmlException)
{
MessageBox.Show("Xml is invalid");
}
}
}
For how to include the end XML tag, I leave that for your own exercise:)
Hope this helps
- Marked as answer by Marco Zhou Friday, July 4, 2008 10:27 AM
Friday, July 4, 2008 4:09 AM