locked
XML view in WPF RRS feed

  • 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,
    Robert
    Monday, 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="=&quot;" Foreground="{StaticResource xmlMarkBrush}"/>
            <TextBlock Text="{Binding Path=Value}" Foreground="{StaticResource xmlValueBrush}"/>
            <TextBlock Text="&quot;" 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="&lt;" 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="&gt;" 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="/&gt;" 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="=&quot;" Foreground="{StaticResource xmlMarkBrush}"/>
            <TextBlock Text="{Binding Path=Value}" Foreground="{StaticResource xmlValueBrush}"/>
            <TextBlock Text="&quot;" 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="&lt;" 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="&gt;" 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,
    Robert
    Wednesday, 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="=&quot;" Foreground="{StaticResource xmlMarkBrush}"/>
            <TextBlock Text="{Binding Path=Value}" Foreground="{StaticResource xmlValueBrush}"/>
            <TextBlock Text="&quot;" 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="&lt;" 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="&gt;" 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="/&gt;" 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