【发布时间】:2015-07-23 13:28:02
【问题描述】:
在我的例子中,输入 xml 必须有一个命名空间声明,其中根元素(即<message>)是其一部分。
在示例 1 中,<message> 元素是命名空间 http://www.origostandards.com/schema/mtg/v2 的一部分。它在 xml 中声明,<message> 元素存在于 xml 中,前缀为 mtg。我拥有的样式表开发符合此要求,但不保留根元素以外的其他元素的名称空间。
如果未声明消息元素所属的命名空间(示例 2),则样式表必须生成具有在根元素中声明的默认命名空间 http://www.origoservices.com 的输出。(参见示例 2)
但是,我开发的样式表在(示例 2)没有分配给元素的命名空间前缀的情况下运行良好,并且不适用于具有以命名空间为前缀的命名空间元素名称的 xml(示例 1) .
示例 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>
声明默认命名空间的 xml 示例 http://www.origoservices.com 是以下示例中的默认命名空间。
<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>
【问题讨论】:
-
我不明白“默认命名空间声明”的含义。您能否提供一个与您的 XSLT 配合良好的 XML 示例?谢谢。
-
@potame 我已通过在其末尾添加示例 xml 来更新问题。我对命名空间概念的理解不是很清楚,因此我可能误称它为“默认命名空间声明”
-
好的,它更清楚一点,但在您预期的 XML 输出中,我没有看到添加任何 默认命名空间。
-
+1 用于识别我的问题中的缺陷。我已经更新了我的问题。但是,基本上我的问题是,在问题中提供的示例 1 的情况下,我开发的样式表不会保留名称空间。
-
@user2607367 stackoverflow.com/help/someone-answers
标签: xml xslt namespaces xslt-1.0 ibm-datapower