84、网络编程与 XML 数据处理

网络编程与 XML 数据处理

1. 异步响应处理与界面更新

在网络请求中, BeginGetResponse() 的回调函数在后台线程运行。若要与界面元素交互,需使用 Dispatcher.BeginInvoke() 将调用封送到前台线程。以下是具体操作步骤:
1. 创建一个用于更新界面的方法,例如:

Private Sub UpdateLabel(text As String)
    lblResult.Text = text
End Sub
  1. ReadResponse() 方法结束时调用此更新方法。为告知 Dispatcher.BeginInvoke() 要调用的方法,可传递指向该方法的委托或创建 Action 对象。使用 Action 对象的方式更简洁,示例代码如下:
' 创建一个表示接受单个字符串参数的方法的操作
' 将操作指向 UpdateLabel()
Dim updateAction As New Action(Of String)(AddressOf UpdateLabel)

' 调用操作并传入新文本
Dispatcher.BeginInvoke(updateAction, result)
2. 使用网络凭据

WebClient WebRequest 类允许在 Web 请求中传递网络凭据(用户名和密码),以访问需要身份验证的安全 Web 服务器。具体操作步骤如下:
1. 调用共享的 WebRequest.RegisterPrefix() 方法,确保使用客户端 HTTP 堆栈:

WebRequest.RegisterPrefix("http://", System.Net.Browser.WebRequestCreator.ClientHttp)
  1. 设置 WebClient WebRequest 对象的 UseDefaultCredentials 属性和 Credentials 属性。以 WebRequest 类为例:
Dim request As WebRequest = WebRequest.Create(address)
request.UseDefaultCredentials = False
request.Credentials = New NetworkCredential("username", "password")

设置完这些属性后,就可以正常使用 WebRequest WebClient 对象与 Web 服务器进行通信。

3. 处理不同类型的数据

从 Web 上检索的数据类型多样,普通文本和 HTML 从编程角度看解析困难,更多时候会处理复杂的结构化数据,如 XML、SOAP 消息或 JSON。Silverlight 支持这三种格式,下面重点介绍 XML 的处理。

4. XML 处理选项

Silverlight 提供了几种处理 XML 的方式:
- XmlWriter 和 XmlReader :提供最基础的 XML 处理方法,功能最少。可逐个元素读写 XML 内容。
- XmlSerializer :能将活动对象转换为 XML 表示形式,反之亦然。但 XML 必须遵循类的结构。使用时需引用 System.Xml.Serialization.dll 程序集。
- XDocument :是 LINQ to XML 的基础,能灵活转换 XML 对象。使用合适的 LINQ 表达式可筛选所需细节并更改内容结构。使用时需引用 System.Xml.Linq.dll 程序集。

一般来说,大多数 Silverlight 应用程序使用高级的 XmlSerializer XDocument 类更好。但如果要处理大量 XML 且想避免一次性将其全部加载到内存中,可能需要使用 XmlWriter XmlReader 进行逐位处理。

以下是不同处理方式的对比表格:
| 处理方式 | 优点 | 缺点 | 适用场景 |
| ---- | ---- | ---- | ---- |
| XmlWriter 和 XmlReader | 基础操作,适合处理大量数据 | 功能少,操作繁琐 | 处理大量 XML 且需逐位处理 |
| XmlSerializer | 能实现对象与 XML 转换 | XML 需遵循类结构 | 完全控制数据格式,无需遵循特定 XML 格式 |
| XDocument | 灵活,支持 LINQ 筛选和转换 | - | 处理他人提供的 XML 数据,如从 Web 服务获取的数据 |

5. 返回 XML 数据的服务示例:Flickr

Flickr 是一个提供 REST 风格服务的图像共享网站,其 Web 服务返回 XML 响应。以下是使用 Flickr 服务检索图片的示例:
1. 构建 Flickr 请求 URL,包含查询字符串参数:

Private Sub cmdGetData_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    Dim client As New WebClient()
    Dim address As New Uri("http://api.flickr.com/services/rest/?" & _
      "method=flickr.photos.search" & "&tags=" & _
      HttpUtility.UrlEncode(txtSearchKeyword.Text) & _
      "&api_key=..." & "&perpage=10")

    AddHandler client.DownloadStringCompleted, _
      AddressOf client_DownloadStringCompleted
    client.DownloadStringAsync(address)
End Sub
  1. 处理返回的 XML 数据:
Private Sub client_DownloadStringCompleted(ByVal sender As Object, ByVal e As DownloadStringCompletedEventArgs)
    Dim document As XDocument = XDocument.Parse(e.Result)

    ' 清空列表
    images.Items.Clear()

    ' 检查每个 <photo> 元素
    For Each element As XElement In document.Descendants("photo")
        ' 获取属性值并组合构建图像 URL
        Dim imageUrl As String = String.Format( _
          "http://farm{0}.static.flickr.com/{1}/{2}_{3}_m.jpg", _
          CStr(element.Attribute("farm")), CStr(element.Attribute("server")), _
          CStr(element.Attribute("id")), CStr(element.Attribute("secret")))

        ' 创建显示图像的 Image 对象
        Dim img As New Image()
        img.Stretch = Stretch.Uniform
        img.Width = 200
        img.Height = 200
        img.Margin = New Thickness(10)
        img.Source = New BitmapImage(New Uri(imageUrl))

        ' 将 Image 元素添加到列表
        images.Items.Add(img)
    Next
End Sub
6. 导航 XDocument

XDocument 包含 XNode 对象集合, XNode 是抽象基类, XElement XComment XText 等类继承自它。 XElement 类的一些重要方法如下表所示:
| 方法 | 描述 |
| ---- | ---- |
| Attributes() | 获取此元素的 XAttribute 对象集合 |
| Attribute() | 获取具有特定名称的 XAttribute (若不匹配则返回 Nothing ) |
| Elements() | 获取此元素包含的 XElement 对象集合。可指定元素名称以筛选 |
| Element() | 获取此元素中具有特定名称的 XElement (若不匹配则返回 Nothing )。若有多个匹配元素,返回第一个 |
| Nodes() | 获取此元素包含的所有 XNode 对象,包括元素和其他内容(如注释) |

通过这些方法可以灵活筛选和访问 XML 元素。例如,在 Flickr 示例中,可通过以下方式访问元素:

Dim photosElement As XElement = document.Element("rsp").Element("photos")

此外, XDocument XElement 类还提供了 Ancestors() Descendants() 方法进行更深入的搜索。 Descendants() 方法可查找当前元素包含的所有 XElement 对象,无论深度如何。例如:

For Each element As XElement In document.Descendants("photo")
7. 使用 LINQ 查询 XDocument

结合 LINQ 表达式可将 XML 内容转换为不同结构。例如,使用 Descendants() 方法选择 XML 文档中的所有 <photo> 元素,并提取重要属性值:

Dim photos = From results In document.Descendants("photo") _
             Select New With { _
                .Id = CStr(results.Attribute("id")), _
                .Farm = CStr(results.Attribute("farm")), _
                .Server = CStr(results.Attribute("server")), _
                .Secret = CStr(results.Attribute("secret"))}

这种将 XML 文档部分内容映射到新类的技术称为投影。可结合匿名类型进行一次性任务,也可使用投影创建自定义类的实例,以进行数据绑定。例如,定义 FlickrImage 类:

Public Class FlickrImage
    Private _imageUrl As String
    Public Property ImageUrl() As String
        Get
            Return _imageUrl
        End Get
        Set(ByVal value As String)
            _imageUrl = value
        End Set
    End Property
End Class

然后使用 LINQ 表达式创建 FlickrImage 对象集合:

Dim photos = From results In document.Descendants("photo") _
             Select New FlickrImage With {.ImageUrl = _
             String.Format( _
               "http://farm{0}.static.flickr.com/{1}/{2}_{3}_m.jpg", _
               results.Attribute("farm").Value.ToString(), _
               results.Attribute("server").Value.ToString(), _
               results.Attribute("id").Value.ToString(), _
               results.Attribute("secret").Value.ToString())}
images.ItemsSource = photos

这种方法代码量最少,解决方案最简洁。

8. XDocument 与命名空间

XDocument 类处理命名空间的方式很优雅。在元素名称前添加用花括号括起来的命名空间。例如,要查找特定命名空间中的 <photos> 元素:

Dim ns As XNamespace = "http://www.somecompany.com/DVDList"
Dim photosElement As XElement = element.Element(ns & "photos")

以下是处理 Flickr 图片检索的流程图:

graph TD;
    A[用户输入搜索关键词] --> B[构建 Flickr 请求 URL];
    B --> C[触发异步下载请求];
    C --> D[下载完成,返回 XML 数据];
    D --> E[解析 XML 数据到 XDocument];
    E --> F[遍历 <photo> 元素];
    F --> G[提取属性值构建图片 URL];
    G --> H[创建 Image 对象并显示图片];
    H --> I[将 Image 元素添加到列表];

通过以上内容,我们了解了网络编程中异步响应处理、使用网络凭据、处理不同类型数据(特别是 XML 数据)的方法,以及如何利用 XDocument 和 LINQ 进行 XML 数据的导航、查询和投影,还掌握了处理命名空间的技巧。这些知识和技术在实际的网络应用开发中具有重要的应用价值。

网络编程与 XML 数据处理

9. 异步操作与界面交互的注意事项

在进行网络请求的异步操作时,由于 BeginGetResponse() 的回调在后台线程运行,若直接在回调中操作界面元素会引发异常。使用 Dispatcher.BeginInvoke() 是解决此问题的关键。具体步骤如下:
- 首先定义更新界面元素的方法,如前面提到的 UpdateLabel 方法:

Private Sub UpdateLabel(text As String)
    lblResult.Text = text
End Sub
  • 然后在异步操作完成后,创建 Action 对象并使用 Dispatcher.BeginInvoke() 调用该操作:
Dim updateAction As New Action(Of String)(AddressOf UpdateLabel)
Dispatcher.BeginInvoke(updateAction, result)
10. 网络凭据的使用场景与优势

在访问需要身份验证的安全 Web 服务器时,网络凭据的使用至关重要。使用网络凭据的步骤如下:
- 调用 WebRequest.RegisterPrefix() 方法确保使用客户端 HTTP 堆栈:

WebRequest.RegisterPrefix("http://", System.Net.Browser.WebRequestCreator.ClientHttp)
  • 设置 WebClient WebRequest 对象的 UseDefaultCredentials Credentials 属性:
Dim request As WebRequest = WebRequest.Create(address)
request.UseDefaultCredentials = False
request.Credentials = New NetworkCredential("username", "password")

使用网络凭据的优势在于可以安全地访问受保护的资源,避免未经授权的访问。

11. XML 处理方式的选择依据

在处理 XML 数据时,选择合适的处理方式取决于具体的需求。以下是不同处理方式的选择依据列表:
- XmlWriter 和 XmlReader
- 适用场景:处理大量 XML 数据,且需要逐位处理,避免一次性将大量数据加载到内存中。
- 示例场景:处理大型日志文件或实时数据流中的 XML 数据。
- XmlSerializer
- 适用场景:完全控制数据格式,不需要遵循特定的 XML 格式,且需要将对象与 XML 进行相互转换。
- 示例场景:自定义数据结构的序列化和反序列化。
- XDocument
- 适用场景:处理他人提供的 XML 数据,需要灵活筛选和转换数据,支持 LINQ 查询。
- 示例场景:从 Web 服务获取的 XML 数据,需要提取特定信息。

12. Flickr 服务的更多应用与优化

Flickr 服务除了简单的图片检索,还可以进行更多的操作,如分页、排序、按日期过滤等。以下是优化 Flickr 请求的步骤:
- 构建包含更多参数的请求 URL:

Dim client As New WebClient()
Dim address As New Uri("http://api.flickr.com/services/rest/?method=flickr.photos.search&tags=frog&api_key=...&perpage=10&page=2&sort=date-taken-desc")
  • 处理返回的 XML 数据时,可以使用 Descendants() 方法更高效地筛选元素:
For Each element As XElement In document.Descendants("photo")
    ' 处理元素
Next
13. LINQ 查询在 XML 处理中的高级应用

LINQ 查询不仅可以用于简单的元素筛选和属性提取,还可以进行更复杂的操作,如分组、排序和聚合。以下是一个示例:

Dim groupedPhotos = From photo In document.Descendants("photo")
                    Group photo By farm = photo.Attribute("farm").Value
                    Into Group
                    Select New With {.Farm = farm, .PhotoCount = Group.Count()}

这个示例将 <photo> 元素按 farm 属性进行分组,并统计每个分组中的元素数量。

14. 命名空间处理的实际应用

在实际开发中,XML 文档可能包含多个命名空间。使用 XNamespace 类可以更方便地处理命名空间。以下是一个示例:

Dim ns1 As XNamespace = "http://namespace1.com"
Dim ns2 As XNamespace = "http://namespace2.com"

Dim element1 As XElement = document.Element(ns1 & "element1")
Dim element2 As XElement = document.Element(ns2 & "element2")
15. 总结与实践建议

通过对网络编程、XML 数据处理、Flickr 服务应用以及 LINQ 查询等方面的学习,我们掌握了一系列实用的技术和方法。在实际开发中,建议遵循以下实践建议:
- 在进行异步网络请求时,始终使用 Dispatcher.BeginInvoke() 处理界面更新,避免线程安全问题。
- 根据具体需求选择合适的 XML 处理方式,优先考虑 XDocument 类的灵活性和 LINQ 查询的强大功能。
- 在使用网络凭据时,确保正确设置 WebRequest.RegisterPrefix() 和相关属性,以确保安全访问。
- 在处理复杂的 XML 数据时,结合 LINQ 查询进行高效的数据筛选和转换。

以下是一个总结性的流程图,展示了从网络请求到 XML 数据处理的整体流程:

graph TD;
    A[发起网络请求] --> B[使用网络凭据(可选)];
    B --> C[异步获取响应];
    C --> D[处理响应数据(如 XML)];
    D --> E[选择合适的 XML 处理方式];
    E --> F[使用 LINQ 查询筛选数据];
    F --> G[更新界面显示结果];

通过这些技术和方法的应用,可以开发出高效、安全且功能强大的网络应用程序。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值