添加新的xml元素并更改同一父元素中元素的值

时间:2014-01-08 12:51:33

标签: xslt xslt-1.0

我需要对我的XML输入进行某些修改,具体取决于某些条件。我正在使用XSLT 1.0。

  1. message_type元素的值(m_cotrol的子元素)应该更改
  2. 应添加新元素message_status(作为m_control元素的子元素)。
  3. 这些更改反映在预期的输出XML中。使用我当前的XSLT代码,我只能达到第二个要求。

    输入XML:

    <?xml version="1.0"?>
    <message xmlns="http://www.origoservices.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <m_control>
        <control_timestamp>2013-04-12T09:24:38.902</control_timestamp>
        <message_id>a50ec030-72ab</message_id>
        <retry_number>0</retry_number>
        <message_type>Request</message_type>
        <message_version>test.XSD</message_version>
        <expected_response_type>synchronous</expected_response_type>
        <initiator_id>FST</initiator_id>
        <initiator_orchestration_id>1637280</initiator_orchestration_id>
        <responder_id>mycomp</responder_id>
      </m_control>
      <m_content>
        <b_control>
          <service_provider_reference_number>650971</service_provider_reference_number>
          <intermediary_case_reference_number>Sample1</intermediary_case_reference_number>
          <quote_type>Comparison</quote_type>
          <quote_or_print>Print</quote_or_print>
          <message_version_number>3.7</message_version_number>
          <submission_date>0001-04-12</submission_date>
        </b_control>
      </m_content>
    </message>
    

    预期输出:

    <message xmlns="http://www.origoservices.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <m_control>
        <control_timestamp>2013-04-12T09:24:38.902</control_timestamp>
        <message_id>a50ec030-72ab</message_id>
        <retry_number>0</retry_number>
        <message_type>Response</message_type>
        <message_version>test.XSD</message_version>
        <expected_response_type>synchronous</expected_response_type>
        <initiator_id>FST</initiator_id>
        <initiator_orchestration_id>1637280</initiator_orchestration_id>
        <responder_id>mycomp</responder_id>
        <message_status>User not allowed access</message_status>
      </m_control>
      <m_content>
        <b_control>
          <service_provider_reference_number>650971</service_provider_reference_number>
          <intermediary_case_reference_number>Sample1</intermediary_case_reference_number>
          <quote_type>Comparison</quote_type>
          <quote_or_print>Print</quote_or_print>
          <message_version_number>3.7</message_version_number>
          <submission_date>0001-04-12</submission_date>
          <quote_response_status>Error</quote_response_status>
          <quote_error_note>
            <reason>[Error] Check if the User has access to the requested service</reason>
          </quote_error_note>
        </b_control>
      </m_content>
    </message>
    

    XSLT代码:根据DataPower变量的值(var:// service / error-message),我需要预期的输出。

    <?xml version="1.0"?>
    
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dp="http://www.datapower.com/extensions" version="1.0" extension-element-prefixes="dp" exclude-result-prefixes="dp">
    
    <xsl:output method="xml" encoding="UTF-8"/>
    
    <xsl:template match="@*|node()">
      <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
    </xsl:template>
    
    <xsl:template match="//*[contains(name(),'m_control')]">
      <xsl:choose>
        <xsl:when test="dp:variable('var://service/error-message') = 'not present'">
          <m_control xmlns="http://www.origoservices.com">
            <xsl:apply-templates select="@* | *"/>
            <message_status>User not recognized</message_status>
          </m_control>
        </xsl:when>
      </xsl:choose>
    </xsl:template>
    
    <xsl:template match="//*[contains(name(),'b_control')]">
      <xsl:choose>
        <xsl:when test="dp:variable('var://service/error-subcode')='0x01d30002'">
          <b_control xmlns="http://www.origoservices.com">
            <xsl:apply-templates select="@* | *"/>
            <quote_response_status>Error</quote_response_status>
            <quote_error_note>
              <reason>[Error] Check if the User has access to the requested service</reason>
            </quote_error_note>
          </b_control>
        </xsl:when>
      </xsl:choose>
    </xsl:template>
    
    </xsl:stylesheet>
    

1 个答案:

答案 0 :(得分:0)

以下样式表符合您的两个要求。它执行常见的身份转换(您的XSLT也会这样做)和异常。

请注意,我没有考虑样式表执行的任何更改,但未将其列为要求(即更改quote_error_notequote_response_status)。

这一行:

<xsl:template match="text()[parent::ori:message_type]">

符合您的第一个要求,即您无法编码的要求。它匹配message_type的文本内容,并输出“Response”。

但是这个解决方案与你的解决方案有所不同:它匹配元素:

<xsl:template match="//*[contains(name(),'m_control')]">

相反,确定了正确的命名空间:

<xsl:template match="ori:m_control">

现在,有什么区别?您描述模板匹配的方式允许匹配任何命名空间的元素。在您的情况下这可能不是问题(没有冲突的命名空间),但它可能是一般的。

完整样式表

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ori="http://www.origoservices.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exclude-result-prefixes="ori xsi">

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

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

<xsl:template match="ori:m_control">
  <xsl:copy>
     <xsl:apply-templates/>
     <message_status>
        <xsl:text>User not allowed access</xsl:text>
     </message_status>
  </xsl:copy>
</xsl:template>


<xsl:template match="text()[parent::ori:message_type]">
  <xsl:text>Response</xsl:text>
</xsl:template>

</xsl:stylesheet>