【问题标题】:Mule XSLT Transformer is adding namespace after transformationMule XSLT Transformer 在转换后添加命名空间
【发布时间】:2014-02-24 22:59:39
【问题描述】:

问题: 我正在尝试将 uuid 作为新元素添加到传入的 xml 消息中。我可以看到在我记录结果时添加了它,但是 mule 将它的命名空间和 java util uuid 命名空间添加到结果中,这导致我路由此消息的另一个服务,不识别它,因为它有一个它没有的命名空间了解一下。

有没有办法配置 xslt 转换器来实现我在这里尝试做的事情?还有其他可以替代的建议吗?

目标是让 xslt 生成一个 uuid 并标记传入消息并将其传递给服务端点。 感谢您在这方面的所有帮助。

骡配置:

<mule xmlns:mulexml="http://www.mulesoft.org/schema/mule/xml"
  xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking"
  xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core"
  xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
  xmlns:spring="http://www.springframework.org/schema/beans" version="EE-3.4.1"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:billing="http://mycompany.com/billing"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd
http://www.mulesoft.org/schema/mule/xml http://www.mulesoft.org/schema/mule/xml/current/mule-xml.xsd">

  <mulexml:xslt-transformer name="xslt"
    doc:name="XSLT">
    <mulexml:xslt-text>
      <xsl:stylesheet version="2.0" xmlns:uuid="java:java.util.UUID">
        <xsl:variable name="uid" select="uuid:randomUUID()" />
        <xsl:template match="/">
          <xsl:apply-templates />
        </xsl:template>

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

        <xsl:template match="Request">
          <Request>
            <xsl:apply-templates select="node()|@*" />
            <RequestId>
              <xsl:value-of select="$uid" />
            </RequestId>
          </Request>
        </xsl:template>
      </xsl:stylesheet>
    </mulexml:xslt-text>
  </mulexml:xslt-transformer>

  <flow name="rsi_invoiceFlow1" doc:name="rsi_invoiceFlow1">
    <http:inbound-endpoint exchange-pattern="request-response"
      address="${listener.hostname}:${listener.port}/${listener.path.invoice.rsi}"
      doc:name="HTTP" transformer-refs="xslt" />


    <logger message="#[message.payloadAs(java.lang.String)]" level="ERROR"
      doc:name="Logger" />

    <http:outbound-endpoint exchange-pattern="request-response"
      method="POST" address="${destination.dev2.url}/" doc:name="HTTP"
      doc:description="The '/' at the end of the URL is required on the RSI outbound call" />
  </flow>
</mule>

传入的 XML:

<?xml version="1.0" encoding="UTF-8"?>
<billing:RQ xmlns:billing="http://mycompany.com/billing">
  <Request>
    <CallingHostOrWeblogicInstance>SOAPUI</CallingHostOrWeblogicInstance>
  </Request>

输出:

<?xml version="1.0" encoding="UTF-8"?>
<billing:RQ xmlns:billing="http://mycompany.com/billing">
<Request xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:uuid="java:java.util.UUID"><CallingHostOrWeblogicInstance xmlns="">SOAPUI</CallingHostOrWeblogicInstance>
<RequestId>bff3e1d6-ecdd-41ae-8807-ec04085a2b54</RequestId>
</Request>

【问题讨论】:

    标签: xml xslt namespaces mule transformer


    【解决方案1】:

    XSLT 在有效的默认命名空间中创建没有指定命名空间的新元素。

    在您的情况下,默认命名空间被声明为 xmlns="http://www.mulesoft.org/schema/mule/core",因此您输出的 &lt;Request&gt; 元素将位于该命名空间中。

    一种方法是完全避免使用默认命名空间。而是使用前缀xmlns:mule="http://www.mulesoft.org/schema/mule/core",然后使用&lt;mule:mule&gt;&lt;mule:flow&gt;&lt;mule:logger&gt; 等。如果您发现mule: 太长,请使用m:

    这可能是最干净的方法。无论如何,您已经在使用许多其他名称空间,明确指出那个名称不会受到伤害。

    另一个变体是在 XSLT 声明中将默认命名空间重置为空:

    <xsl:stylesheet 
       version="2.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
       xmlns:uuid="java:java.util.UUID" 
       xmlns=""
    >
      <!-- ... -->
    </xsl:stylesheet>
    

    您也可以使用&lt;xsl:copy&gt; 而不是显式创建一个新的&lt;Request&gt; - 但是您仍然会遇到与&lt;RequestId&gt; 相同的问题。 &lt;RequestId xmlns=""&gt; 可以解决这个问题,但它相当丑陋,特别是如果它不是您创建的唯一元素。

    如果您不想外部化 XSLT(正如 David 建议的那样),我建议您使用“无默认命名空间”方法。

    【讨论】:

      【解决方案2】:

      不要将 XSL 嵌入到 Mule 配置本身中,而是存储在独立文件中。您将避免命名空间污染,这是最佳实践。

      【讨论】:

        【解决方案3】:

        在 xsl:stylesheet 元素上使用 xmlns="" 来重置默认命名空间。

        在 xsl:stylesheet 元素中使用 exclude-result-prefixes 以避免其他 mule 命名空间泄漏到样式表中。

        (您也可以使用 XML 1.1 “名称空间取消声明”,它是为此目的而发明的,但我不会这样做:XML 1.1 没有得到足够广泛的支持,无法使该技术变得健壮。)

        【讨论】:

          【解决方案4】:

          我尝试了所有 3 条建议,我认为将转换与流配置分开最适合我的情况,因为它提供了解决此问题的最简洁和解耦的方法。

          谢谢大家的回复。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-07-04
            • 2021-05-17
            • 2010-12-16
            • 2016-04-27
            • 2021-08-26
            • 2015-07-20
            • 1970-01-01
            相关资源
            最近更新 更多