-1

在我的情况下,输入 xml 必须具有命名空间的声明,其中根元素(即<message>)是 .

在示例 1 中,<message>元素是命名空间的一部分。http://www.origostandards.com/schema/mtg/v2它在 xml 中声明,并且<message>元素存在于带有前缀的 xml 中mtg。我开发的样式表符合此要求,但不为其他人保留命名空间元素比根元素。如果未声明消息元素所属的命名空间(示例 2),则样式表必须生成具有http://www.origoservices.com在根元素中声明的默认命名空间的输出。(参见示例 2)

但是,我开发的样式表在(示例 2)没有分配给元素的名称空间前缀的情况下运行良好,并且不适用于名称空间元素名称以名称空间(示例 1)为前缀的 xml。

示例 1 输入 xml

<?xml version="1.0"?>
<mtg:message xmlns:ce="http://www.origostandards.com/schema/ce/v2" xmlns:mtg="http://www.origostandards.com/schema/mtg/v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<mtg:m_control id="m_control1">
    <mtg:control_timestamp>2014-12-18T10:06:00-05:00</mtg:control_timestamp>
    <mtg:message_id>c5-a4e0-aa0090358c7f</mtg:message_id>
    <mtg:retry_number>0</mtg:retry_number>
    <mtg:expected_response_type>synchronous</mtg:expected_response_type>
    <mtg:initiator_id>temp</mtg:initiator_id>
    <mtg:responder_id/>
</mtg:m_control>
<ce:m_content>
    <ce:b_control>
        <ce:reference>xyz</ce:reference>
    </ce:b_control>
</ce:m_content>
</mtg:message>

实际输出

 <?xml version="1.0" encoding="UTF-8"?>
 <mtg:message xmlns:ce="http://www.origostandards.com/schema/ce/v2" xmlns:mtg="http://www.origostandards.com/schema/mtg/v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<m_control xmlns="http://www.origostandards.com/schema/mtg/v2" id="m_control1">
    <control_timestamp>2014-12-18T10:06:00-05:00</control_timestamp>
    <message_id>c5-a4e0-aa0090358c7f</message_id>
    <retry_number>0</retry_number>
    <expected_response_type>synchronous</expected_response_type>
    <initiator_id>temp</initiator_id>
    <responder_id/>
</m_control>
<m_content xmlns="http://www.origostandards.com/schema/mtg/v2">
    <b_control>
        <reference>xyz</reference>
    </b_control>
</m_content>
</mtg:message>

预期产出

 <?xml version="1.0"?>
 <mtg:message xmlns:ce="http://www.origostandards.com/schema/ce/v2" xmlns:mtg="http://www.origostandards.com/schema/mtg/v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <mtg:m_control id="m_control1">
    <mtg:control_timestamp>2014-12-18T10:06:00-05:00</mtg:control_timestamp>
    <mtg:message_id>c5-a4e0-aa0090358c7f</mtg:message_id>
    <mtg:retry_number>0</mtg:retry_number>
    <mtg:expected_response_type>synchronous</mtg:expected_response_type>
    <mtg:initiator_id>temp</mtg:initiator_id>
    <mtg:responder_id/>
</mtg:m_control>
<ce:m_content>
    <ce:b_control>
        <ce:reference>xyz</ce:reference>
    </ce:b_control>
</ce:m_content>
</mtg:message>

示例 2 - 该输入 xml 的样式表按预期工作

<message>
  <m_control>
    <control_timestamp>2014-11-05T09:30:38.308</control_timestamp>
    <retry_number>0</retry_number>
    <expected_response_type>synchronous</expected_response_type>
     <responder_id>Exchange Life 1</responder_id>
   </m_control>
</message>

预期和实际产出

<message xmlns="http://www.origoservices.com">
<m_control>
  <control_timestamp>2014-11-05T09:30:38.308</control_timestamp>
  <retry_number>0</retry_number>
  <expected_response_type>synchronous</expected_response_type>
  <responder_id>Exchange Life 1</responder_id>
 </m_control>
 </message>

我的样式表

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dp="http://www.datapower.com/extensions" xmlns:regexp="http://exslt.org/regular-expressions" extension-element-prefixes="dp" xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="dp regexp exsl">
      <xsl:output method="xml" indent="yes" version="1.0"/>

       <xsl:variable name="origo-svc-ns" select="'http://www.origoservices.com'"/>

      <!--xsl:template match="/message"-->
      <xsl:template match="/*[local-name()='message']">
         <xsl:variable name="name" select="name()"/>
         <xsl:variable name="namespace-in" select="namespace-uri(/*[1])"/>
         <xsl:variable name="initiator_id" select="/*[local-name()='message']/*[local-name()='m_control']/*[local-name()='initiator_id']"/>

   <!--Below code tests if default namespace declaration is present. If not, then assigns the 'default namespace' to 'namespace' variable. Also, it assigns context variable  "AddNamespace"  with value "Y" if default namespace declaration is not present -->       

         <xsl:variable name="namespace">
                  <xsl:choose>
                      <xsl:when test="$namespace-in = '' and ($initiator_id = 'True Potential' or $initiator_id = '2Plan' or $initiator_id = '356356536' or $initiator_id = 'Assyst Software') ">
                              <xsl:value-of select="$origo-svc-ns"/>
                              <dp:set-variable name="'var://context/FL/AddNamspace'" value="'Y'"/>
                      </xsl:when>
                     <xsl:otherwise>
                              <xsl:value-of select="$namespace-in"/>
                     </xsl:otherwise>
                </xsl:choose>
      </xsl:variable>

     <!-- - In below statement, {$namespace} will copy over the default namespace declarartion to the destination.
  - copy-of select statement will copy over all the namespace declaration in the source xml 
  - apply-template will copy over evrything else from the source to destination
  - xsl:element wil create an element node (in this case <message> ) in the destination document.      
    -->

    <xsl:element name="{$name}" namespace="{$namespace}">
       <xsl:copy-of select="namespace::*"/>
      <xsl:apply-templates select="@*|node()|comment()|processing-instruction()|text()">
      <xsl:with-param name="ns-uri" select="$namespace"/>

     </xsl:apply-templates>
     </xsl:element>
  </xsl:template>

  <xsl:template match="node()">

    <xsl:param name="ns-uri"/>
    <xsl:element name="{local-name()}" namespace="{$ns-uri}">
     <xsl:copy-of select="namespace::*"/>
       <xsl:apply-templates select="@*|node()|comment()|processing-instruction()|text()">
        <xsl:with-param name="ns-uri" select="$ns-uri"/>
       </xsl:apply-templates>
     </xsl:element>
  </xsl:template>

  <xsl:template match="@*|comment()|processing-instruction()|text()">
       <xsl:param name="ns-uri"/>
       <xsl:copy>
      <xsl:apply-templates select="@*|node()|comment()|processing-instruction()|text()">
        <xsl:with-param name="ns-uri" select="$ns-uri"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

具有声明为http://www.origoservices.com的默认命名空间的 xml 示例是以下示例中的默认命名空间。

  <message xmlns="http://www.origoservices.com" xmlns:a="https://www.bbb.com">
  <m_control>
    <control_timestamp>2014-11-05T09:30:38.308</control_timestamp>
    <message_id>2840c35d-d294-4179-baa1-55ea2ce0b9ac</message_id>
    <retry_number>0</retry_number>
    <message_type>Quotation Request</message_type>
          <message_version>/origo/3.7/QNBPensionAnnuityQuoteRequest.xsd</message_version>
    <expected_response_type>synchronous</expected_response_type>
    <initiator_id>Friends Provident</initiator_id>
       <initiator_orchestration_id>2944460</initiator_orchestration_id>
    <responder_id>Exchange Life 1</responder_id>
</m_control>
 </message>
4

2 回答 2

0

有点乱,我不明白你为什么不使用<xsl:copy-of>指令。

这样的样式表要简单得多,并且可以正确完成工作(我已经删除了第一个模板中的一些代码,因为我没有发现它对我们感兴趣的问题有任何用处:

<xsl:stylesheet version="1.0" 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:dp="http://www.datapower.com/extensions" 
        xmlns:regexp="http://exslt.org/regular-expressions" 
        xmlns:ce="http://www.origostandards.com/schema/ce/v2"
        xmlns:mtg="http://www.origostandards.com/schema/mtg/v2"
        xmlns:exsl="http://exslt.org/common" 
        exclude-result-prefixes="dp regexp exsl">

    <xsl:output method="xml" indent="yes" version="1.0"/>

    <xsl:variable name="origo-svc-ns" select="'http://www.origoservices.com'"/>

    <xsl:template match="/message">
        <xsl:variable name="name" select="name()"/>


     <!-- - In below statement, {$namespace} will copy over the default namespace declarartion to the destination.
  - copy-of select statement will copy over all the namespace declaration in the source xml 
  - apply-template will copy over evrything else from the source to destination
  - xsl:element wil create an element node (in this case <message> ) in the destination document.      
    -->

      <xsl:element name="{$name}" namespace="{$origo-svc-ns}">
        <!--xsl:copy-of select="namespace::*"/-->
        <xsl:apply-templates select="@*|node()|comment()|processing-instruction()|text()" />
      </xsl:element>
    </xsl:template>

    <xsl:template match="* | mtg:* | ce:*">
        <xsl:copy-of select="."/>
    </xsl:template>

</xsl:stylesheet>

一些解释:

  1. 首先我声明mtgce命名空间,以便我可以在样式表中使用它们。
  2. 然后我匹配并处理<message>没有附加命名空间的元素。复制此元素并附加适当的命名空间,并处理子元素
  3. 所有其他元素都简单地复制到输出中,以及所有子元素(和命名空间)。

我已经用这两个条目检查了这段代码(XML 示例 1 和 2)。

于 2015-05-13T12:30:28.577 回答
0

你的问题很难理解,如果不是不可能的话。与您之前的问题(这是一个衍生问题)相同,它缺乏明确的目的陈述。

如果我们假设您只希望您的样式表在根元素位于默认命名空间(或没有命名空间)时执行某种转换,而当它不在时(即它有前缀)执行另一个转换,那么这可能是很简单地实现了,例如:

<xsl:template match="/">
    <xsl:choose>
        <xsl:when test="name(*)=local-name(*)">
            <!-- root element is in a default or no namespace; apply transformation A -->
        </xsl:when>
        <xsl:otherwise>
            <!-- root element has a prefix; apply transformation B -->
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>
于 2015-05-13T15:24:58.163 回答