【问题标题】:Remove XML element with empty child in WSO2 ESB 4.0.3在 WSO2 ESB 4.0.3 中删除带有空子元素的 XML 元素
【发布时间】:2018-04-12 05:08:29
【问题描述】:

我在 ESB 中设置了一个直通代理 Web 服务,它从 DSS 端点获取数据,类似于以下内容:

<Products xmlns="http://wso2.host.com/Products">
    <Product>
        <SKU>12345678</SKU>
        <ItemName xmlns="null">T Shirt</ItemName>
        <Restrictions>
            <Restriction>
                <Reason>Reason A</Reason>
                <Code>12</Code>
            </Restriction>
        </Restrictions>
    </Product>
</Products>

产品可能没有限制,并且会通过这种可能性:

<Products xmlns="http://wso2.host.com/Products">
    <Product>
        <SKU>12345678</SKU>
        <ItemName xmlns="null">T Shirt</ItemName>
        <Restrictions>
            <Restriction>
                <Reason/>
                <Code/>
            </Restriction>
        </Restrictions>
    </Product>
</Products>

我想删除整个 &lt;Restrictions&gt; 元素,以便响应显示如下:

<Products xmlns="http://wso2.host.com/Products">
    <Product>
        <SKU>12345678</SKU>
        <ItemName xmlns="null">T Shirt</ItemName>
    </Product>
</Products>

我正在尝试在 out 序列中使用丰富的中介来将其替换为空,但我不确定用什么来替换它,或者这是否真的是最好的方法。我的Xpath表达式如下:

/Products/Product/Restrictions[string-length(Restriction/Reason[text()])=0]

非常感谢任何帮助,我对 WSO2 不是很熟悉,可能完全错过了正确的答案。提前致谢。


更新:我遵循了@Jorge Infante Osorio 的建议并添加了一个 XSLT 中介,它引用了一个本地条目,定义如下:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" />

<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="Restrictions"/>
</xsl:stylesheet>

这仍然不工作。但是,我可以通过添加 3 个 XSLT 中介并将它们指向这个本地条目来删除它们:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output omit-xml-declaration="yes" indent="yes" />
    <xsl:strip-space elements="*" />
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*" />
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*[not(node())]   |    *[not(node()[2])    and      node()/self::text()    and      not(normalize-space())      ]   " />
</xsl:stylesheet>

我尝试修改它以匹配 @Jorge Infante Osorio 在他的示例中使用的限制模板,但我似乎无法正确。

【问题讨论】:

  • 尝试将上一个模板中的匹配更改为match="Restrictions[not(normalize-space())]"。如果这不起作用,请确保 Restrictions 不在默认命名空间中。
  • @DanielHaley 您的第一个建议不起作用 - 但我注意到我在根元素上确实有一个我没有包含的命名空间。编辑了我的答案以包括这一点 - 是什么影响了模板?
  • 是的,就是这样做的。请看下面我的回答。希望对您有所帮助!
  • 我的回答有帮助吗?

标签: xslt wso2 wso2esb


【解决方案1】:

尝试使用以下 XSLT...

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:p="http://wso2.host.com/Products">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="p:Restrictions[not(normalize-space())]"/>

</xsl:stylesheet>

请注意,我已经考虑了默认命名空间 http://wso2.host.com/Products

【讨论】:

  • 做到了!谢谢!我在 XSLT 之前还有一个 Enrich 调解器,必须将它移到 XSLT 之后才能工作。
【解决方案2】:

由于您的有效负载会根据输出不断变化,因此建议您使用 XSLT 中介,原因是您的序列会变小并且可读性会增加。

【讨论】:

    【解决方案3】:

    我的测试代理:

    <?xml version="1.0" encoding="UTF-8"?>
    <proxy xmlns="http://ws.apache.org/ns/synapse"
           name="testReplacement"
           transports="http https"
           startOnLoad="true"
           statistics="enable"
           trace="enable">
       <description/>
       <target>
          <inSequence>
             <log level="custom">
                <property name="ACCESO A: "
                          value="Accediendo replacement TEST"/>
             </log>
                <payloadFactory media-type="xml">
                  <format>
                     <Products xmlns="">
                        <Product>
                            <SKU>12345678</SKU>
                            <ItemName>T Shirt</ItemName>
                            <Restrictions>
                                <Restriction>
                                    <Reason></Reason>
                                    <Code></Code>
                                </Restriction>
                            </Restrictions>
                        </Product>
                      </Products>               
                  </format>
                  <args>
                  </args>
                </payloadFactory>   
                <property name="razon" expression="//Products/Product/Restrictions/Restriction/Reason/text()"/>
                <property name="longitudValue" expression="fn:string-length(get-property('razon'))"/>
                <log level="custom">
                  <property name="BODY = " expression="$ctx:body"/>
                  <property name="razon" expression="$ctx:razon"/>
                  <property name="longitudValue" expression="$ctx:longitudValue"/>
                </log>
                <filter source="$ctx:longitudValue" regex="0.0"> 
                   <then> 
                      <log level="custom"> 
                         <property name="RESULTADO" value="Esta vacio"/> 
                      </log> 
                    <xslt key="transformacionDeleteEmpty"/>         
                    <log level="custom">
                      <property name="BODY = " expression="$ctx:body"/>
                    </log>              
                   </then> 
                   <else> 
                      <log level="custom"> 
                         <property name="RESULTADO" value="No esta vacio"/> 
                      </log> 
                   </else> 
                </filter>
                <respond/>          
          </inSequence>
          <outSequence>
             <log level="full"/>
             <drop/>
          </outSequence>
          <faultSequence/>
       </target>
    </proxy>
    

    XSLT:

    <?xml version="1.0" encoding="UTF-8"?>
    <localEntry key="transformacionDeleteEmpty" xmlns="http://ws.apache.org/ns/synapse">
    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" />
    
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    
    <xsl:template match="Restrictions"/>
    </xsl:stylesheet>
    </localEntry>
    

    控制台输出:

    [2018-04-06 11:21:53,210]  INFO - LogMediator ACCESO A:  = Accediendo replacement TEST
    [2018-04-06 11:21:53,214]  INFO - LogMediator BODY =  = <soapenv:Body xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><Products><Product><SKU>12345678</SKU><ItemName>T Shirt</I
    temName><Restrictions><Restriction><Reason/><Code/></Restriction></Restrictions></Product></Products></soapenv:Body>, razon = , longitudValue = 0.0
    [2018-04-06 11:21:53,215]  INFO - LogMediator RESULTADO = Esta vacio
    [2018-04-06 11:21:53,249]  INFO - LogMediator BODY =  = <soapenv:Body xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><Products>
      <Product>
        <SKU>12345678</SKU>
        <ItemName>T Shirt</ItemName>
        <Restrictions>
          <Restriction>
            <Reason/>
            <Code/>
          </Restriction>
        </Restrictions>
      </Product>
    </Products></soapenv:Body>
    [2018-04-06 11:21:53,307]  INFO - LogMediator BODY =  = <soapenv:Body xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><Products>
      <Product>
        <SKU>12345678</SKU>
        <ItemName>T Shirt</ItemName>
    
      </Product>
    </Products></soapenv:Body>
    

    【讨论】:

    • 我试过了,但最终结果没有删除元素。请查看我更新的问题描述。
    • 你确定吗?,检查我的代理我使用与你相同的 XML 以及它从 EI 控制台获取的输出!!!可能是因为您使用的 ESB 4.0.3 是一个非常旧的版本。
    猜你喜欢
    • 2015-05-14
    • 1970-01-01
    • 2014-11-18
    • 1970-01-01
    • 2016-06-13
    • 2012-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多