SSIS Xpath查询表达式错误

时间:2014-12-17 15:59:10

标签: sql-server xml xpath ssis

我试图通过SSIS调用SalesForce Web服务,我正在尝试检索sessionID节点的值。

这是XML:

 <?xml version="1.0" encoding="utf-16"?>
<LoginResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <metadataServerUrl xmlns="urn:partner.soap.sforce.com">https://xxxxxx/services/Soap/m/31.0/xxxxxx</metadataServerUrl>
  <passwordExpired xmlns="urn:partner.soap.sforce.com">false</passwordExpired>
  <sandbox xmlns="urn:partner.soap.sforce.com">true</sandbox>
  <serverUrl xmlns="urn:partner.soap.sforce.com">https://xxx/services/Soap/u/31.0/xxx</serverUrl>
  <sessionId xmlns="urn:partner.soap.sforce.com">xxxxxxxxxx</sessionId>
  <userId xmlns="urn:partner.soap.sforce.com">xxx</userId>
  <userInfo xmlns="urn:partner.soap.sforce.com">
    <accessibilityMode>false</accessibilityMode>
    <currencySymbol>$</currencySymbol>
    <orgAttachmentFileSizeLimit>5242880</orgAttachmentFileSizeLimit>
    <orgDefaultCurrencyIsoCode>USD</orgDefaultCurrencyIsoCode>
    <orgDisallowHtmlAttachments>false</orgDisallowHtmlAttachments>
    <orgHasPersonAccounts>false</orgHasPersonAccounts>
    <organizationId>xxxxxxxx</organizationId>
    <organizationMultiCurrency>false</organizationMultiCurrency>
    <organizationName>xxxxx</organizationName>
    <profileId>xxxxx</profileId>
    <roleId xsi:nil="true" />
    <sessionSecondsValid>7200</sessionSecondsValid>
    <userDefaultCurrencyIsoCode xsi:nil="true" />
    <userEmail>xxxxxxx</userEmail>
    <userFullName>xxxxx</userFullName>
    <userId>xxxxxxx</userId>
    <userLanguage>en_US</userLanguage>
    <userLocale>en_US</userLocale>
    <userName>xxxxxxx</userName>
    <userTimeZone>America/New_York</userTimeZone>
    <userType>Standard</userType>
    <userUiSkin>Theme3</userUiSkin>
  </userInfo>
</LoginResult>

我通过http://www.xpathtester.com/xpath成功测试了这个表达式。

编辑: 现在尝试编写脚本任务,但我仍然没有找到准确的组合来选择此信息。 XML中有多个名称空间,下面的代码返回0个节点。相当令人沮丧!

public void Main()
    {
        string loginResult;
        string sessionID;

        loginResult = Dts.Variables["User::loginResult"].Value.ToString();

        XmlDocument doc = new XmlDocument();
        doc.LoadXml(loginResult);

        var xmlnsManager = new System.Xml.XmlNamespaceManager(doc.NameTable);
        //xmlnsManager.AddNamespace("t1", "http://www.w3.org/2001/XMLSchema-instance");

        xmlnsManager.AddNamespace("ns", "urn:partner.soap.sforce.com");

        XmlNodeList list = doc.SelectNodes("/LoginResult/ns:sessionID", xmlnsManager);

        for (int i = 0; i < list.Count; i++)
        {
            sessionID = list[i].Value;
        }

        Dts.TaskResult = (int)ScriptResults.Success;
    }
}

1 个答案:

答案 0 :(得分:2)

找到sessionId元素的正确表达式是:

//*[local-name() = 'sessionId']/text()

在您的输入XML中,您要查找的元素:

<sessionId xmlns="urn:partner.soap.sforce.com">xxxxxxxxxx</sessionId>

具有前缀 - 它位于默认命名空间中,不需要为元素添加前缀。 因此,可能的解释是像

这样的表达式
//*:sessionId

只查找输入XML中带前缀的元素。这应该不是问题,但据我所知,SSIS以命名空间XML的问题而闻名(例如参见herehere)。

就XPath规范而言,像//*:root这样的表达式应该能够找到像

这样的元素
<root xmlns="www.example.com"/>

编辑:显然,您已经完全改变了问题 - 现在还有另一个问题:最外面的元素LoginResult完全位于 no 命名空间中,而不是在xsi:命名空间中:

<LoginResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>

架构实例命名空间恰好在此元素上声明,但在那里不使用它。因此,请将代码更改为:

var xmlnsManager = new System.Xml.XmlNamespaceManager(doc.NameTable);

xmlnsManager.AddNamespace("ns", "urn:partner.soap.sforce.com");

XmlNodeList list = doc.SelectNodes("/LoginResult/ns:sessionId", xmlnsManager);