-1

私の場合、入力 xml には、ルート要素 (つまり<message>) が含まれる名前空間の宣言が必要です。

例 1 では、<message>要素は名前空間の一部です。xml でhttp://www.origostandards.com/schema/mtg/v2宣言され、<message>要素は xml 内に接頭辞 で存在しmtgます。私が開発したスタイルシートはこの要件に準拠していますが、他の要素の名前空間を保持していません。ルート要素よりも要素。メッセージ要素が含まれる名前空間が宣言されていない場合 (例 2)、スタイルシートは、ルート要素で宣言されたデフォルトの名前空間を持つ出力を生成する必要がありますhttp://www.origoservices.com(例 2 を参照)。

ただし、私が開発したスタイルシートは、要素に名前空間プレフィックスが割り当てられていない場合 (例 2) にうまく機能し、名前空間要素名の前に名前空間 (example1) が付いている 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. mtg最初にと名前空間を宣言しceて、スタイルシートで使用できるようにします。
  2. <message>次に、名前空間が関連付けられていない要素を照合して処理します。この要素は、適切な名前空間が付加された状態でコピーされ、子要素が処理されます
  3. 他のすべての要素は、すべてのサブ要素 (および名前空間) とともに出力に単純にコピーされます。

このコードを両方のエントリ (XML の例 1 と 2) で確認しました。

于 2015-05-13T12:30:28.577 に答える