在 WSO2 迭代调解器上定义的这个 XPATH 表达式到底是如何工作的?

How exactly works this XPATH expression defined on the WSO2 iterate mediatior?

我正在研究 WSO2 EIP 模式,阅读 splitter 模式的官方文档时我有一些疑问 (https://docs.wso2.com/display/IntegrationPatterns/Splitter)

从理论的角度来看,我很清楚,我对示例提出的实现有一些疑问。

它正在定义此代理,其中包含一个实现 splitter 模式的序列:

<definitions xmlns="http://ws.apache.org/ns/synapse">
   <proxy name="SplitMessageProxy" transports="http https" startOnLoad="true">
      <target>
         <inSequence>
            <log level="full"/>
            <iterate xmlns:m0="http://services.samples"
                     preservePayload="true"
                     attachPath="//m0:getQuote"
                     expression="//m0:getQuote/m0:request">
               <target>
                  <sequence>
                     <send>
                        <endpoint>
                           <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
                        </endpoint>
                     </send>
                  </sequence>
               </target>
            </iterate>
         </inSequence>
         <outSequence>
            <drop/>
         </outSequence>
      </target>
      <publishWSDL uri="file:repository/samples/resources/proxy/sample_proxy_1.wsdl"/>
   </proxy>
   <sequence name="fault">
      <log level="full">
         <property name="MESSAGE" value="Executing default &#34;fault&#34; sequence"/>
         <property name="ERROR_CODE" expression="get-property('ERROR_CODE')"/>
         <property name="ERROR_MESSAGE" expression="get-property('ERROR_MESSAGE')"/>
      </log>
      <drop/>
   </sequence>
   <sequence name="main">
      <in/>
      <out/>
   </sequence>
</definitions>

然后这个 SOAP 请求 被发送到 previus 代理:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.samples" xmlns:xsd="http://services.samples/xsd">
   <soapenv:Header/>
   <soapenv:Body>
      <ser:getQuote>    
         <ser:request>          
            <xsd:symbol>IBM</xsd:symbol>
         </ser:request>
          <ser:request>           
            <xsd:symbol>WSO2</xsd:symbol>
         </ser:request>
         <ser:request>          
            <xsd:symbol>IBM</xsd:symbol>
         </ser:request>
      </ser:getQuote>
   </soapenv:Body>
</soapenv:Envelope>

好的,所以 Iterate 中介 获取在其 XPath 表达式中指定的元素的每个子元素,并在迭代器中介内应用序列流...所以在这种情况下它正在迭代 XPATH 表达式 的所有子项,定义如下://m0:getQuote/m0:request XML 标签:

<xsd:symbol>IBM</xsd:symbol>

<xsd:symbol>WSO2</xsd:symbol>

<xsd:symbol>IBM</xsd:symbol>

这个XPATH表达式的疑点是:

XPATH 表达式是 //m0:getQuote/m0:request。为什么在此示例中它在 XML 元素之前附加 m0 名称空间?为什么表达式不是 //ser:getQuote/ser:request(使用进入 ESB 流的 XML 请求中定义的名称空间)?

在 Iterate Mediator 本身中定义的命名空间 m0。 xmlns:m0="http://services.samples" 这就是我们在 Xpath 中使用它的原因。 前缀 "m0" 无关紧要,命名空间的 uri 很重要。 我们可能只是不知道传入消息将以什么前缀到达。

重要的是命名空间,前缀只是引用先前定义的命名空间的一种简单方式。

在请求中,前缀 ser 定义为

xmlns:ser="http://services.samples"

在迭代中介中,m0 前缀定义为

xmlns:m0="http://services.samples"

解析XPATH表达式时实际使用的是命名空间,因此两者解析相同。不同文档之间的前缀不必相似,它们仅在文档内有效。因此 m0 前缀仅限于 WSO2 代理,而 ser 前缀特定于您的请求。