使用PowerShell PNP读取SharePoint多行字段提取纯文本的方法
问题背景
我有一个PowerShell脚本,可读取SharePoint列表的多数字段并写入SQL文件,分两步完成SharePoint列表到SQL Server的导出操作。但多行字段始终以HTML格式导出,示例如下:
"<div class="ExternalClass1692C959C37B4AE2B2A5251BCEB89A3A"><p>?<span style="color:#444444;font-family:"segoe ui", "segoe ui", segoe, tahoma, helvetica, arial, sans-serif;">TEXT TO EXTRACT</span>?<br></p></div>"
我已能处理姓名、邮箱、URL等字段类型,将数组值转成分隔字符串,但HTML输出处理困难。当前使用的拆分方法会残留 这类HTML实体,需手动替换,效果不理想。想找基于PowerShell PNP的HTML解析逻辑,直接读取核心文本并忽略所有HTML。此前找到过CSOM的类似方案,但文档不完善,多数资料仅涉及如何创建多行列。
现有脚本片段:
#Override the default, if applicable If($listItem[$title]){ $field = $listItem[$title].ToString() Else { If(($field -like "Microsoft.SharePoint.Client.*") -and ($field -notlike '*`[`]')){ If($field.Split('.')[3] -eq 'FieldUserValue') { $item += $listItem[$title].LookupValue.ToString() } ElseIf($field.Split('.')[3] -eq 'FieldUrlValue') { $item += $listItem[$title].URL.ToString() } ElseIf ($listItem[$title].LookupValue) { $item += $listItem[$title].LookupValue.ToString() } Else { $item += '' } } ElseIf(($field -like "Microsoft.SharePoint.Client.*") -and ($field -like '*`[`]')){ If($field.Split('.')[3] -eq 'FieldUserValue') { #For each person in the array #Get the email value and convert to a name foreach($arr_value in $listItem[$title]) { $item += $arr_value.Email.ToString().Split("@")[0].Replace(".", " ") -Replace('[^a-zA-Z ]','') $item += "$delim" } } Else { #Get each Lookup value in the array and add it to a comma-delimited string foreach($arr_value in $listItem[$title]) { If ($arr_value.LookupValue) { $item += $arr_value.LookupValue.ToString() } Else { $item += '' } $item += "$delim" } $item = $item.Substring(0, $item.Length - $($delim).Length) } }
当前临时解决方案:
If($field.Substring(0,11) -eq '<div class='){ $item += $($field.Split('>')[3]).Replace('</span', '') }
解决方案
方法1:使用HtmlAgilityPack解析HTML
适合需要精准处理复杂HTML结构的场景,无需依赖GUI组件:
- 安装模块:
Install-Module -Name HtmlAgilityPack
- 编写解析函数:
Import-Module HtmlAgilityPack function Convert-HtmlToPlainText { param( [string]$HtmlContent ) if([string]::IsNullOrWhiteSpace($HtmlContent)) { return '' } $htmlDoc = New-Object HtmlAgilityPack.HtmlDocument $htmlDoc.LoadHtml($HtmlContent) # 提取纯文本并自动解码HTML实体 $plainText = $htmlDoc.DocumentNode.InnerText.Trim() # 清理多余空白字符 $plainText = $plainText -replace '\s+', ' ' return $plainText }
- 在原有脚本中调用函数处理多行字段:
ElseIf($field -match '<div class="ExternalClass'){ $item += Convert-HtmlToPlainText -HtmlContent $field }
方法2:使用.NET原生类处理(无需额外模块)
适合快速实现,依赖.NET内置类完成实体解码和标签移除:
- 编写解析函数:
function Convert-HtmlToPlainText { param( [string]$HtmlContent ) if([string]::IsNullOrWhiteSpace($HtmlContent)) { return '' } # 解码HTML实体(如 转为空格) $decoded = [System.Net.WebUtility]::HtmlDecode($HtmlContent) # 移除所有HTML标签 $plainText = $decoded -replace '<[^>]+>', '' # 清理多余空白字符 $plainText = $plainText -replace '\s+', ' ' return $plainText.Trim() }
- 同样在原有脚本的字段判断逻辑中调用该函数即可。
整合后的完整字段处理示例
#Override the default, if applicable If($listItem[$title]){ $field = $listItem[$title].ToString() } Else { $field = '' } # 处理不同字段类型 If(($field -like "Microsoft.SharePoint.Client.*") -and ($field -notlike '*`[`]')){ If($field.Split('.')[3] -eq 'FieldUserValue') { $item += $listItem[$title].LookupValue.ToString() } ElseIf($field.Split('.')[3] -eq 'FieldUrlValue') { $item += $listItem[$title].URL.ToString() } ElseIf ($listItem[$title].LookupValue) { $item += $listItem[$title].LookupValue.ToString() } Else { $item += '' } } ElseIf(($field -like "Microsoft.SharePoint.Client.*") -and ($field -like '*`[`]')){ If($field.Split('.')[3] -eq 'FieldUserValue') { #For each person in the array #Get the email value and convert to a name foreach($arr_value in $listItem[$title]) { $item += $arr_value.Email.ToString().Split("@")[0].Replace(".", " ") -Replace('[^a-zA-Z ]','') $item += "$delim" } } Else { #Get each Lookup value in the array and add it to a comma-delimited string foreach($arr_value in $listItem[$title]) { If ($arr_value.LookupValue) { $item += $arr_value.LookupValue.ToString() } Else { $item += '' } $item += "$delim" } $item = $item.Substring(0, $item.Length - $($delim).Length) } } ElseIf($field -match '<div class="ExternalClass'){ # 处理多行HTML字段 $item += Convert-HtmlToPlainText -HtmlContent $field } Else { # 其他普通字段直接赋值 $item += $field }
内容的提问来源于stack exchange,提问作者n8.
相关产品推荐
相关产品推荐

