网络编程与 XML 数据处理
1. 异步响应处理与界面更新
在网络请求中,
BeginGetResponse()
的回调函数在后台线程运行。若要与界面元素交互,需使用
Dispatcher.BeginInvoke()
将调用封送到前台线程。以下是具体操作步骤:
1. 创建一个用于更新界面的方法,例如:
Private Sub UpdateLabel(text As String)
lblResult.Text = text
End Sub
-
在
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)
-
设置
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
- 处理返回的 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[更新界面显示结果];
通过这些技术和方法的应用,可以开发出高效、安全且功能强大的网络应用程序。
超级会员免费看

被折叠的 条评论
为什么被折叠?



