代码之家  ›  专栏  ›  技术社区  ›  Leth

使用body path表达式从wcf-sql消息提取xml节点中的xml文档

  •  0
  • Leth  · 技术社区  · 6 年前

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

    我在适配器的配置设置的“body-path-expression”输入字段中尝试了一些xpath表达式,但它们似乎都没有达到我预期的效果。

    我尝试过的一些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中。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Dijkgraaf José Ignacio Gutiérrez Guzmán    6 年前

    第一个xpath几乎是正确的,只是前两个节点的名称空间丢失了。

    [1] 在您的第一个示例中,除非有多个节点并且您希望选择第一个节点,否则您的xpath示例是必需的。

    正确的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;