独上高楼网站
  •    你所在位置:首页 Windows经验小经验〉使用 Windows 窗体构建 XPath Visualizer
  • 使用 Windows 窗体构建 XPath Visualizer
  • 作者:佚名  文章来源:网上下载  发布日期:2007-06-14  浏览次数:633
  • 打印这篇文章
  • Prajakta Joshi
    Microsoft Corporation

    适用于:
    Microsoft Windows
    XML 编程

    摘要:Praj Joshi 制作了一个 GUI 工具,用于查看 XPath 对 XML 文档的查询结果。该工具是使用 XPathReader 和 .NET WinForms 类构建的。

    *

    单击此处可下载本文的代码示例。

    本页内容
    简介 简介
    XPath Viewer 设计目标 XPath Viewer 设计目标
    XPath Viewer 一瞥 XPath Viewer 一瞥
    功能概述 功能概述
    一些限制 一些限制
    小结 小结
    致谢 致谢

    简介

    作为 XML 测试小组的一员,我与组内的其他同事开发了大量用于测试我们产品的工具。我发现其中有一个工具很有用,该工具是我用 XPathReader 类编写的,用于显示与用户指定的 XPath 表达式匹配的 XML 文档中的节点。本文描述了 XPath Viewer 工具,并附带了相关代码以供下载。

    XPath Viewer 设计目标

    当我着手编写 XPath Viewer 工具时,我为自己设定了以下设计目标:

    1.

    简单、轻量级应用程序,用于测试 XPath 表达式。

    2.

    当它保存在文件中时,提供简洁的 XML 视图(类似“记事本”)而不是树视图(Internet Explorer 样式)。

    3.

    在 XML 中突出显示选择的 XPath 节点。

    4.

    在网格视图中显示每个匹配节点的属性。

    5.

    允许用户利用命名空间执行查询。

    6.

    允许用户在提供的命名空间管理器中轻松添加/删除命名空间 prefixURI 值。

    7.

    该应用程序必须能够运行在满足下列最低要求的系统上:

    ?

    Microsoft Windows 2000、Windows XP 或更高版本。

    ?

    Microsoft .NET Framework 1.1。

    XPath Viewer 一瞥

    查看器工作区被划分为四个区域。下面的图 1 显示 UI 的快照。

    xpathviewer1thumb

    图 1. UI 查看器快照

    该 UI 的大部分区域是相当直观的。

    ?

    在左上部面板中,您可以输入 XPath 表达式。并且,如果您希望对 XML 文件进行“片段”查询,那么您应该选择该复选框。

    ?

    在右上部“Namespaces”网格中,您可以编辑命名空间 的值。该数据网格提供了 XpathCollection 类中 NamespaceManger 对象内容的概况。

    ?

    左下部“XML”面板是一个只读 RichTextBox 控件,它显示加载的 XML 文件内容。

    ?

    右下部面板以数据网格形式显示“Selected XPathReader Nodes”。(显而易见,这是只读的。)

    功能概述

    编辑命名空间

    XPathCollection 类用于指定当针对 XPath 表达式匹配节点时由 XPathReader 使用的 绑定。“Namespaces”网格只提供了 XPathCollection 类中命名空间管理器的概况。该网格通过 DataGrid 类实现。它的 DataSource 属性设置为 DataTable 并且 DataTableRowDeletingRowChanged 事件用于处理 XPathCollection 的命名空间管理器(如下所示)。

    private void namespaces_RowDeleting( object sender, DataRowChangeEventArgs e )
    {   
       this.xpc.NamespaceManager.RemoveNamespace(e.Row[0].ToString(),
        e.Row[1].ToString());
    }
    
    private void namespaces_RowChanged( object sender, DataRowChangeEventArgs e )
    {   
       this.xpc.NamespaceManager.AddNamespace(e.Row[0].ToString(),
        e.Row[1].ToString());
    }
    

    初始化 XPathReader

    当用户加载 XML 文件时,就是用流式 XmlTextReader 类适当地加载 XpathReader(作为文档或片段)。接下来,使用 XmlReaderXPathCollection 对象创建 XPathReader 的实例。

    if (checkBoxFrag.Checked)
    {
       FileStream strmTemp = new FileStream(xmlFile, FileMode.Open,
      FileAccess.Read);
       XmlParserContext parserContext = new XmlParserContext(new NameTable(),
        null, null, XmlSpace.Default);
       this.xtr = new XmlTextReader(strmTemp, XmlNodeType.Element, parserContext);   
    }
    else               
    {
       this.xtr = new XmlTextReader(xmlFile);   
    }
    this.xpr = new XPathReader(xtr, xpc);
    this.xpc.Clear();
    this.xpc.Add(textBoxExpr.Text);
    

    显示匹配的节点

    我使用 RichTextBox 类以类似于记事本的视图显示 XML。该类公开了一个 Select() 方法,我可以使用该方法突出显示控件内的文本。这里列出部分代码,这段代码调用 XPathReaderReadUntilMatch() 循环访问匹配节点。

    while (this.xpr.ReadUntilMatch())
    {   
       switch (this.xpr.NodeType)
       {
          case XmlNodeType.Element:
          case XmlNodeType.EndElement:
          case XmlNodeType.Attribute:
          case XmlNodeType.ProcessingInstruction:
             startPos = this.GetStartPosition(xtr.LineNumber, xtr.LinePosition);
             richTextBoxXml.Select(startPos, xpr.Name.Length);
             this.AddNode();
             break;
    
          case XmlNodeType.Comment:
          case XmlNodeType.Whitespace:
          case XmlNodeType.SignificantWhitespace:
          case XmlNodeType.Text:
             startPos = this.GetStartPosition(xtr.LineNumber, xtr.LinePosition);
             richTextBoxXml.Select(startPos, xpr.Value.Length);
             this.AddNode();
             break;
                   
          case XmlNodeType.Document:
          case XmlNodeType.DocumentFragment:
          case XmlNodeType.DocumentType:
          case XmlNodeType.Entity:
          case XmlNodeType.EntityReference:
          case XmlNodeType.EndEntity:
          case XmlNodeType.Notation:
          case XmlNodeType.XmlDeclaration:
          case XmlNodeType.None:
          default:
          MessageBox.Show("XPath 1.0 data model does not define node of type "
     + xpr.NodeType, "Bug in XPathReader", MessageBoxButtons.OK);
             break;
       }
    }
    

    正如您所见,一些 XmlNodeType 值不能通过 XPath 表达式匹配,原因是 XPath 1.0 数据模型不支持这些节点类型。(该框架中的 XPathNavigator 类使用枚举 XpathNodeType 取而代之。)匹配的节点不仅突出显示,它们还会在数据网格中显示。上面显示的 AddNode() 方法为每个匹配的节点都添加了一个新行。

    更改 Reader 属性以进行显示

    下面的图 2 显示如何才能编辑 reader 属性以实现在网格中的显示。由于我不会缓存任意有关匹配的 reader 节点的信息,因此列中的更改在下一次执行查询时生效。

    xpathviewer2thumb

    图 2. 编辑 reader 属性

    一些限制

    ?

    我使用表面语言下面的 XPathReader 实现,与 XPathReader 一样,该工具支持 XPath 1.0 子集。

    ?

    XPathReader 类的用途是使用户能够根据添加到 XPathCollection 的多个 Xpath 表达式匹配当前的 reader 节点。XPath Viewer 不支持多个 XPath 表达式。

    ?

    如果突出显示节点,则可以更好地显示选择的节点。但是,RichTextBox 控件不支持在 .NET Framework 版本 1.1 中更改文本的背景色。此外,扩展控件以增加这一功能也没什么价值。告诉您一个好消息,在 Visual Studio 2005 Beta 1 版本提供对该功能的支持。

    小结

    在本文中,我介绍了 XPath Viewer 工具,它能够使您轻松测试 XPath 查询,并且可以作为了解 XPath 或调试复杂的 XPath 查询的工具。我希望所有的 XML 开发人员都能像我一样认同这个工具是很有用的。

    致谢

    我非常感谢 Dare Obasanjo 为本文提供的思路以及 Howard Hao 在修复一些 XPathReader 错误方面提供的支持。我还要感谢 Tejal Joshi 对本文代码的校对以及对 WinForms 提供的有用提示。

    Prajakta Joshi 是 WebData XML 小组的测试软件设计工程师。

    转到原英文页面

  • 打印这篇文章
  • 与本文主题相关的文章
  • 返回首页