WSO2 ESB:简单的XSLT消息转换问题

时间:2016-02-04 12:07:41

标签: xslt wso2esb

如下所示,我的XSLT不会将for-each表达式包装在父元素中,因为我需要它。我需要将所有消息元素包含在消息父元素中。

我有一个存储以下XSLT样式表的本地条目:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" version="1.0">
<xsl:param name="page_id"/>
<xsl:param name="thread_id"/>
<xsl:template match="/">
    <messages xmlns="http://ws.apache.org/ns/synapse">
    <xsl:apply-templates/> 
    </messages>
</xsl:template>
<xsl:template match="//soapenv:Body/jsonObject">
    <xsl:for-each select="/data">
    <message xmlns="http://ws.apache.org/ns/synapse">
      <Page_ID><xsl:value-of select="$page_id"/></Page_ID>
      <Thread_ID><xsl:value-of select="$thread_id"/></Thread_ID>
      <Message_ID><xsl:value-of select="id"/></Message_ID>
      <From_Name><xsl:value-of select="from/name"/></From_Name>
      <From_ID><xsl:value-of select="from/id"/></From_ID>
      <To_Name><xsl:value-of select="to/data/name"/></To_Name>
      <To_ID><xsl:value-of select="to/data/id"/></To_ID>
      <Message><xsl:value-of select="message"/></Message>
      <Attachment_URL><xsl:value-of select="attachments/data/image_data/url"/></Attachment_URL>
      <Created_Date><xsl:value-of select="created_time"/></Created_Date>
    </message>
    </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

我通过像这样的代理服务调用XSLT中介:

<xslt key="Facebook_Transform_Messages" source="$body">
  <property name="page_id" expression="$ctx:page_id"/>
  <property name="thread_id" expression="$ctx:thread_id"/>
</xslt>

传递给服务的数据如下所示:

<jsonObject>
  <data>
    <from>
      <name>James Strain</name>
      <email>10153389835751312@facebook.com</email>
      <id>10153389835751312</id>
    </from>
    <to>
      <data>
        <name>Symphony Council</name>
        <email>409521282507981@facebook.com</email>
        <id>409521282507981</id>
      </data>
    </to>
    <created_time>2016-02-03T13:09:08+0000</created_time>
    <message>test55</message>
    <id>m_mid.1454504948354:03a56a0154cef57406</id>
  </data>
</jsonObject>

转型后:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
  <message xmlns="http://ws.apache.org/ns/synapse">
  <Page_ID>409521282507981</Page_ID>
  <Thread_ID>t_mid.1450744554432:5789f650412eb3fd70</Thread_ID>
  <Message_ID>m_mid.1454553062384:420772e48d9196bd75</Message_ID>
  <From_Name>James Strain</From_Name>
  <From_ID>10153389835751312</From_ID>
  <To_Name>Symphony Council</To_Name>
  <To_ID>409521282507981</To_ID>
  <Message>test70</Message>
  <Attachment_URL/>
  <Created_Date>2016-02-04T02:31:02+0000</Created_Date>
  </message>
</soapenv:Body>
</soapenv:Envelope

更新1

我根据Cis提供的答案更新了我的样式表。但它还没有解决我的问题。尽管如此,WSO2还是不会完全遵循XSLT,实际上将我的for-each操作包装在一个元素中!我用有效载荷数据的副本(整个SOAP信封)here对此进行了测试,它运行正常!发生了什么事?

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:param name="page_id"/>
<xsl:param name="thread_id"/>
<xsl:template match="/">
    <xsl:apply-templates/>
</xsl:template>
<xsl:template match="jsonObject">
    <xsl:element name="messages">
         <xsl:for-each select="data">
            <xsl:element name="message">
               <xsl:element name="Page_ID"><xsl:value-of select="$page_id"/></xsl:element>
               <xsl:element name="Thread_ID"><xsl:value-of select="$thread_id"/></xsl:element>
               <xsl:element name="Message_ID"><xsl:value-of select="id"/></xsl:element>
               <xsl:element name="From_Name"><xsl:value-of select="from/name"/></xsl:element>
               <xsl:element name="From_ID"><xsl:value-of select="from/id"/></xsl:element>
               <xsl:element name="To_Name"><xsl:value-of select="to/data/name"/></xsl:element>
               <xsl:element name="To_ID"><xsl:value-of select="to/data/id"/></xsl:element>
               <xsl:element name="Message"><xsl:value-of select="message"/></xsl:element>
               <xsl:element name="Attachment_URL"><xsl:value-of select="attachments/data/image_data/url"/></xsl:element>
               <xsl:element name="Created_Date"><xsl:value-of select="created_time"/></xsl:element>
               </xsl:element>
         </xsl:for-each>
     </xsl:element>
</xsl:template>
</xsl:stylesheet>

1 个答案:

答案 0 :(得分:0)

我在XSLT代码中看到了XPath表达式中的两个问题:

  1. //soapenv:Body/jsonObject:尾随//match属性中没有意义,因为XSLT处理器将遍历每个元素,无论它们处于哪个级别,检查如果它适合match。更严重的可能是您的示例输入代码中没有soapenv:Body元素,这意味着,模板match属性永远不能评估为true,因此,模板永远不会被执行。如果在示例代码中,jsonObject仅用于此特定位置(而不是:用于输入XML中您不希望它的位置通过此模板处理)您可以简单地将其设置为<xsl:template match="jsonObject">

  2. <xsl:for-each select="/data">中,/错误。您正在尝试选择根元素(不是data),以选择子元素,只需执行select="data"