使用正文路径表达式从 WCF-SQL 消息中提取 XML 节点中的 XML 文档

Extracting XML document in XML node from WCF-SQL message using body path expression

我正在从 WCF-SQL 适配器中的 SQL 服务器接收消息。在此消息中有一个 XML 节点,其中包含作为字符串的完全格式化的 XML 文档。我需要的是仅提取此文档,忽略正文的其余部分,以便它可以由管道进一步处理。

我在适配器配置设置的 "body path expression" 输入字段中尝试了一堆 xPath 表达式,但其中 none 似乎按我期望的方式工作。

我尝试过的一些 xPath 字符串:

    /Polling/PolledData[1]/*[namespace-uri()='http://schemas.datacontract.org/2004/07/System.Data' and local-name()='DataSet'][1]/*[namespace-uri()='urn:schemas-microsoft-com:xml-diffgram-v1' and local-name()='diffgram'][1]/*[namespace-uri()='' and local-name()='NewDataSet'][1]/*[namespace-uri()='' and local-name()='NewTable'][1]/*[namespace-uri()='' and local-name()='msgbody'][1]

    /*[local-name()='Polling']/*[local-name()='PolledData']/*[local-name()='DataSet']/*[local-name()='diffgram']/*[local-name()='NewDataSet']/*[local-name()='NewTable']/*[local-name()='msgbody']

    /Polling/PolledData/DataSet/diffgr:diffgram/NewDataSet/NewTable/msgbody

    //*[msgbody]/text()

我收到的 XML 文档的正文结构如下,我试图从末尾提取内容的 XML 节点:

<Polling xmlns="http://schemas.microsoft.com/Sql/2008/05/Polling/">
    <PolledData>
        <DataSet xmlns="http://schemas.datacontract.org/2004/07/System.Data">
            <xs:schema id="NewDataSet" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
                <xs:element msdata:IsDataSet="true" name="NewDataSet">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element minOccurs="0" maxOccurs="unbounded" name="NewTable">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element minOccurs="0" name="conversationID" type="xs:string"/>
                                        <xs:element minOccurs="0" name="hostUTC" type="xs:dateTime"/>
                                        <xs:element minOccurs="0" name="msgType" type="xs:string"/>
                                        <xs:element minOccurs="0" name="acknowledgment" type="xs:string"/>
                                        <xs:element minOccurs="0" name="sendLog" type="xs:string"/>
                                        <xs:element minOccurs="0" name="msgFormat" type="xs:string"/>
                                        <xs:element minOccurs="0" name="msgbody" type="xs:string"/>
                                        <xs:element minOccurs="0" name="fromID" type="xs:string"/>
                                        <xs:element minOccurs="0" name="toID" type="xs:string"/>
                                    </xs:sequence>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:schema>
            <diffgr:diffgram xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
                <NewDataSet xmlns="">
                    <NewTable>
                        <conversationID>b4327577-14d1-478d-9e22-027683c0c5f9</conversationID>
                        <hostUTC>2018-11-19T13:17:07.03Z</hostUTC>
                        <msgType>INVOIC</msgType>
                        <msgFormat>oioUBL</msgFormat>
                        <msgbody>&lt;Invoice xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

我不确定如何将正确的 xPath 正确写入此节点。阅读 MS docs 上的文档似乎表明我需要使用本地名称语法。我认为我的问题在于在收到的 XML 中使用名称空间,但我不知道如何将这些包含在 xPath 中。

您的第一个 XPath 几乎是正确的,只是您缺少前两个节点的命名空间。

您的第一个 XPath 示例中的 [1] 也是必需的,除非有多个节点并且您希望 select 第一个。

正确的 Xpath 应该是

/*[local-name()='Polling' and namespace-uri()='http://schemas.microsoft.com/Sql/2008/05/Polling/']
/*[local-name()='PolledData' and namespace-uri()='http://schemas.microsoft.com/Sql/2008/05/Polling/']
/*[local-name()='DataSet' and namespace-uri()='http://schemas.datacontract.org/2004/07/System.Data']
/*[local-name()='diffgram' and namespace-uri()='urn:schemas-microsoft-com:xml-diffgram-v1']
/*[local-name()='NewDataSet' and namespace-uri()='']
/*[local-name()='NewTable' and namespace-uri()='']
/*[local-name()='msgbody' and namespace-uri()='']

但我可能仍然遇到问题,因为看起来您的其余有效负载已被转义,例如< 是 &lt;