有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Spring WS transformingInterceptor XSLT复制请求

我试图修改进入Spring WS-webservice的SOAP请求。我使用转换拦截器来转换文档,但不是修改现有值,而是使用修改后的值发出重复请求

以下是我的XSLT代码(仅限于xsl 1.0版):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*" />

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:choose>
                <xsl:when test="text() != '' ">
                    <xsl:call-template name="string-replace-all">
                        <xsl:with-param name="text" select="text()" />
                        <xsl:with-param name="replace" select="'Yoshi'" />
                        <xsl:with-param name="by" select="'Cannot do that here'" />
                    </xsl:call-template>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:apply-templates select="@*|node()"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:copy>
    </xsl:template>

    <xsl:template name="string-replace-all">
        <xsl:param name="text"/>
        <xsl:param name="replace"/>
        <xsl:param name="by"/>
        <xsl:choose>
            <xsl:when test="contains($text,$replace)">
                <xsl:value-of select="substring-before($text,$replace)"/>
                <xsl:value-of select="$by"/>
                <xsl:call-template name="string-replace-all">
                    <xsl:with-param name="text" select="substring-after($text,$replace)"/>
                    <xsl:with-param name="replace" select="$replace"/>
                    <xsl:with-param name="by" select="$by"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$text"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

一个示例SOAP请求:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header />
   <soapenv:Body>
      <LinkRequest>
         <PayorFirstName>Jimmy</PayorFirstName>
         <PayorLastName>Test</PayorLastName>
         <Description>Some top secret test</Description>
         <CustomMessage>Eat it, Yoshi</CustomMessage>
      </LinkRequest>
   </soapenv:Body>
</soapenv:Envelope>

以及转换后请求的外观:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header />
   <soapenv:Body>
      <LinkRequest>
         <PayorFirstName>Jimmy</PayorFirstName>
         <PayorLastName>Test</PayorLastName>
         <Description>Some top secret test</Description>
         <CustomMessage>Eat it, Yoshi</CustomMessage>
      </LinkRequest>
      <LinkRequest>
         <PayorFirstName>Jimmy</PayorFirstName>
         <PayorLastName>Test</PayorLastName>
         <Description>Some top secret test</Description>
         <CustomMessage>Eat it, Cannot do that here</CustomMessage>
      </LinkRequest>
   </soapenv:Body>
</soapenv:Envelope>

我想在请求中搜索一个单词的所有实例(在本例中为“Yoshi”),并将这些实例替换为其他实例(在本例中为“此处不能这样做”)


共 (1) 个答案

  1. # 1 楼答案

    当我将样式表应用于输入XML时,它会生成以下XML,因此我认为XSLT是正确的,但捕获样式表并写回结果的代码可能会再次将其插入正文中

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
      <soapenv:Header />
      <soapenv:Body>
        <LinkRequest>
          <PayorFirstName>Jimmy</PayorFirstName>
          <PayorLastName>Test</PayorLastName>
          <Description>Some top secret test</Description>
          <CustomMessage>Eat it, Cannot do that here</CustomMessage>
        </LinkRequest>
      </soapenv:Body>
    </soapenv:Envelope>
    

    然而,我想为您的XSLT样式表建议一种稍微不同的方法。因为,如前所述,它不考虑嵌套或混合(元素和文本)的内容节点,它还将搜索SOAP主体之外的部分(为了简洁起见,我省略了string-replace-all模板):

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="xml" indent="yes"/>
        <xsl:strip-space elements="*" />
    
        <xsl:template match="node()|@*">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
    
        <xsl:template match="text()[parent::*[not(namespace-uri(.) = 'http://schemas.xmlsoap.org/soap/envelope/')]]">
            <xsl:call-template name="string-replace-all">
                <xsl:with-param name="text" select="." />
                <xsl:with-param name="replace" select="'Yoshi'" />
                <xsl:with-param name="by" select="'Cannot do that here'" />
            </xsl:call-template>
        </xsl:template>
    
    </xsl:stylesheet>