You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用Risport70获取CUCM电话实时数据时XML节点解析异常求助

问题:CUCM RIS API返回的ns1:CMNodes节点无法正常解析(PowerShell)

我在通过PowerShell调用CUCM的RISService70获取电话实时信息时遇到异常:前面的节点都能正常钻取,但访问*<ns1:CMNodes>*节点后,其下所有子节点被合并成一个大字符串,无法通过Select-Node等方式查询子节点。

调用代码如下:

$RisBody = "<soapenv:Envelope xmlns:soapenv=`"http://schemas.xmlsoap.org/soap/envelope/`" xmlns:soap=`"http://schemas.cisco.com/ast/soap`">
   <soapenv:Header/>
   <soapenv:Body>
      <soap:selectCmDevice>
         <soap:StateInfo></soap:StateInfo>
         <soap:CmSelectionCriteria>
            <soap:MaxReturnedDevices>1000</soap:MaxReturnedDevices>
            <soap:DeviceClass>Phone</soap:DeviceClass>
            <soap:Model>255</soap:Model>
            <soap:Status>Any</soap:Status>
            <soap:NodeName></soap:NodeName>
            <soap:SelectBy>Name</soap:SelectBy>
            <soap:SelectItems>
               <soap:item>
                  <soap:Item>SEPABCDEF123456</soap:Item>
               </soap:item>
            </soap:SelectItems>
            <soap:Protocol>Any</soap:Protocol>
            <soap:DownloadStatus>Any</soap:DownloadStatus>
         </soap:CmSelectionCriteria>
      </soap:selectCmDevice>
   </soapenv:Body>
</soapenv:Envelope>"

$RisRequest = Invoke-RestMethod 'https://CUCM:8443/realtimeservice2/services/RISService70?wsdl' -Method 'POST' -Headers $headers -Body $RisBody

我尝试过Invoke-WebRequest、将InnerXml/OuterXml转为[xml]类型,均未解决问题,似乎RisPort70在<CMNodes>节点后将所有内容转为字符串,请问是否必须通过粗暴方式解析?


解决方案

不用粗暴解析,问题出在RIS API的命名空间处理和PowerShell的XML解析逻辑上,试试以下几种可行方案:

1. 重新包裹CMNodes片段为完整XML文档

提取<CMNodes>的原始XML字符串,补上正确的命名空间后转为XML对象:

# 获取CMNodes的原始内容字符串
$cmNodesRaw = $RisRequest.Envelope.Body.selectCmDeviceResponse.selectCmDeviceReturn.SelectCmDeviceResult.cmnodes.InnerXml

# 用带命名空间的根节点包裹片段,生成完整XML
$cmNodesXml = [xml]"<root xmlns:soap='http://schemas.cisco.com/ast/soap'>$cmNodesRaw</root>"

# 现在可以正常查询子节点,比如获取所有Node节点
$cmNodesXml.SelectNodes("//soap:Node")

2. 使用命名空间管理器直接查询原始XML

给原始XML对象添加命名空间管理器,指定RIS API的命名空间后直接查询:

# 创建命名空间管理器
$nsManager = New-Object System.Xml.XmlNamespaceManager($RisRequest.NameTable)
$nsManager.AddNamespace("soap", "http://schemas.cisco.com/ast/soap")

# 直接查询<CMNodes>下的子节点
$RisRequest.SelectNodes("//soap:CMNodes/soap:Node", $nsManager)

3. 改用Invoke-WebRequest手动解析XML

Invoke-RestMethod可能会自动处理命名空间导致节点被转成字符串,换成Invoke-WebRequest后手动解析:

$response = Invoke-WebRequest -Uri 'https://CUCM:8443/realtimeservice2/services/RISService70?wsdl' -Method POST -Headers $headers -Body $RisBody
$xmlResponse = [xml]$response.Content

# 添加命名空间管理器并查询
$nsManager = New-Object System.Xml.XmlNamespaceManager($xmlResponse.NameTable)
$nsManager.AddNamespace("soap", "http://schemas.cisco.com/ast/soap")
$xmlResponse.SelectNodes("//soap:CMNodes/soap:Node", $nsManager)

原因说明

RISService70返回的XML中,<CMNodes>节点下的子节点使用了默认命名空间,但PowerShell的Invoke-RestMethod在自动解析时,没有正确处理嵌套的命名空间关联,导致子节点被识别为纯文本字符串。通过手动添加命名空间或重新包裹XML片段,可以让解析器正确识别节点结构。


内容的提问来源于stack exchange,提问作者sdcrytek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 05:35:05