How to remove some tags without removing the conte

2019-08-08 17:25发布

I am working on XSLT.

Source XML:

           <?xml version="1.0" encoding="iso-8859-1"?>
            <Content>
              <alertHeader>


                <ol xmlns="http://www.w3.org/1999/xhtml">
                  <li>
                    <strong>Review</strong>
                    your current available balance. It can be obtained 24 hours a day, 7 days a week through
                    <a href="/ALL_UNDER_123">Account Activity</a>
                    any 123 ATM or by calling
                    <a id="dynamicvariable" href="#" name="Customercare">[Customercare]</a>
                    at
                    <a id="dynamicvariable" href="#" name="contactNo">[contactNo]</a>
                    .
                  </li>
                  <li>
                    <strong>Take into consideration</strong>


                    <ul>
                      <li>Please get in touch with us</li>
                      <li>Please consider this as important info</li>
                    </ul>


                  </li>
                  <li>
                    <strong>Current</strong>
                    Statementt doesnot match the requirement
                    <a id="dynamicvariable" href="#" name="Actual acccount">[Actual acccount]</a>
                    ,plus
                    <a id="dynamicvariable" href="#" name="totalcharges">[totalcharges]</a>
                    Make u r response as positive.
                  </li>
                </ol>
                <p xmlns="http://www.w3.org/1999/xhtml"></p>
                <div xmlns="http://www.w3.org/1999/xshtml"></div>
                <span xmlns="http://www.w3.org/1999/xshtml"></span>



              </alertHeader>
            </Content>

I want to write a XSLT to pass entire content in the tag alertHeader as value to another template.

I want to modify this code as follows.

                   1.Remove the tags   <p></p>, and <div></div>,<span></span> and <a></a>. I want to remove only tags but not the value of the tags. It should be there as it is.
                   2.Pass the content including tags to "Process" template.

Output required:

          <aaa>
            <text>

            <ol xmlns="http://www.w3.org/1999/xhtml">
              <li>
                    <strong>Review</strong>
                    your current available balance. It can be obtained 24 hours a day, 7 days a week through
                <dynamicvariable name="Customercare"/>

                at
                <dynamicvariable name="contactNo"/>

                .
              </li>
              <li>
                    <strong>Take into consideration</strong>


                    <ul>
                      <li>Please get in touch with us</li>
                      <li>Please consider this as important info</li>
                    </ul>


                  </li>
              <li>
                <strong>Current</strong>
                    Statementt doesnot match the requirement
              </li>
            </ol>
            </text>
          </aaa>

current XSLT:

              <?xml version="1.0" encoding="utf-8"?>
              <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
                <xsl:output method="xml" indent="yes"/>


                <xsl:template match="alertHeader">
                  <xsl:call-template name="process">

                    <xsl:with-param name="text" select="." />


                  </xsl:call-template>

                </xsl:template>
                <xsl:template name="process">
                  <xsl:param name="text" />

                  <xsl:variable name="head" select="substring-before($text, '[')" />
                  <xsl:variable name="tag" select="substring-before(substring-after($text, '['), ']')" />
                  <xsl:variable name="tail" select="substring-after($text, ']')" />

                  <xsl:choose>
                    <xsl:when test="$head != '' and $tag != ''">
                      <xsl:value-of select="$head" />
                      <dynamicVariable name="{$tag}" />
                      <!-- recursive step: process the remainder of the string -->
                      <xsl:call-template name="process">
                        <xsl:with-param name="text" select="$tail" />
                      </xsl:call-template>
                    </xsl:when>
                    <xsl:otherwise>
                      <xsl:value-of select="$text" />
                    </xsl:otherwise>
                  </xsl:choose>
                </xsl:template>

              </xsl:stylesheet>

Can any one say what all the changes required for my code.

Thanks.

标签: xslt xslt-1.0
2条回答
成全新的幸福
2楼-- · 2019-08-08 17:52

There is no need to do any initial processing of the XML document and then pass it to the process template. From looking at your question, it looks like you have a requirement (which you haven't explicitly mentioned) to transform 'tags' in the text, such as form '[Total_Fee]', to dynamicVariable elements.

So, what you need to do is firstly just have a template to ignore your chosen nodes, but continue matching the elements and text within them.

<xsl:template match="Content|alertHeader|xhtml:p|xshtml:div|xshtml:span|xhtml:a">
  <xsl:apply-templates select="@*|node()"/>
</xsl:template>

Do note the complication here is that you have defined different namespaces for some of your nodes (and these would have to be declared in the XSLT document). If you have multiple namespaces, you could also do the following.

<xsl:template match="Content|alertHeader|*[local-name() = 'p']|*[local-name() = 'span']|*[local-name() = 'div']|*[local-name() = 'a']">

Without namespaces you could do the following

<xsl:template match="Content|alertHeader|p|div|span|a">

Next, your named process template can then be combined to match text() elements

<xsl:template match="text()" name="process">

This allows it to match text elements, and recursively call itself to look for tags within the text.

Here is the full XSLT

<xsl:stylesheet version="1.0" 
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
   xmlns:xhtml="http://www.w3.org/1999/xhtml" 
   xmlns:xshtml="http://www.w3.org/1999/xshtml"
   exclude-result-prefixes="xhtml xshtml">

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

   <xsl:template match="Content|alertHeader|xhtml:p|xshtml:div|xshtml:span|xhtml:a">
      <xsl:apply-templates select="@*|node()"/>
   </xsl:template>

   <xsl:template match="text()" name="process">
      <xsl:param name="text" select="." />

      <xsl:choose>
         <xsl:when test="contains($text, ']') and contains($text, '[')">
            <xsl:value-of select="substring-before($text, '[')"/>
            <dynamicVariable name="{substring-before(substring-after($text, '['), ']')}"/>
            <xsl:call-template name="process">
               <xsl:with-param name="text" select="substring-after($text, ']')"/>
            </xsl:call-template>
         </xsl:when>
         <xsl:otherwise>
            <xsl:value-of select="$text"/>
         </xsl:otherwise>
      </xsl:choose>
   </xsl:template>

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

When applied to your XML, the following is output

<ol xmlns="http://www.w3.org/1999/xhtml">
<li>
<strong>Review</strong>                     your current available balance. It can be obtained 24 hours a day, 7 days a week through                     Account Activity                     any Wells Fargo ATM or by calling                     <dynamicVariable name="Call_Center_Name" xmlns="" />                     at                     <dynamicVariable name="Phone_Number" xmlns="" />                     .                   </li>
<li>
<strong>Take into account</strong>
<ul>
<li>Your pending transactions and any additional transactions that have not yet been deducted from your available balance, such as checks you have written or upcoming scheduled automatic payments.</li>
<li>Any transactions that have been returned because you did not have enough money in your account at that time; they may be resubmitted for payment by the person or party who received the payment from you</li>
</ul>
</li>
<li>
<strong>Deposit</strong>                     enough money to establish and maintain a positive account balance. A deposit of at least                     <dynamicVariable name="Absolute_Available_Balance" xmlns="" />                     ,plus                     <dynamicVariable name="Total_Fee" xmlns="" />                     in fees, would have been required to make your account balance positive at the time we sent this notice.                   </li>
</ol>
查看更多
Summer. ? 凉城
3楼-- · 2019-08-08 17:53

The problem in xslt-1.0 is that you can't access a result node or nodeset, as in there is no XPath or function or anything to refer to the transformation result of a template.

Is it essential that you call process as it is? The way I'd go about this is to make process a template that transforms exactly one node, and then call it from every node below alertHeader, like:

<xsl:template match="alertHeader">
  <!-- switch modes so we know we need to call process -->
  <xsl:apply-templates mode="callproc"/>
</xsl:template>

<xsl:template match="*" mode="callproc">
  <!-- call process on THIS node -->
  <xsl:call-template name="process">
    <xsl:with-param name="text" select="."/>
  </xsl:call-template>
  <!-- descend -->
  <xsl:apply-templates mode="callproc"/>
</xsl:template>

<!-- all the stuff that needs stripping -->
<xsl:template match="p|div|span|a" mode="callproc">
  <!-- call process on the text() portion -->
  <xsl:call-template name="process">
    <xsl:with-param name="text" select="text()"/>
  </xsl:call-template>
  <!-- no descent here -->
</xsl:template>

Update: Without process template

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xh="http://www.w3.org/1999/xhtml"
  xmlns:xsh="http://www.w3.org/1999/xshtml">

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

  <xsl:template match="Content">
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="alertHeader">
    <xsl:element name="aaa">
      <xsl:element name="text">
        <!-- switch modes so we know we need to call process -->
        <xsl:apply-templates/>
      </xsl:element>
    </xsl:element>
  </xsl:template>

  <xsl:template match="*">
    <xsl:copy>
      <!-- descend -->
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

  <!-- all the stuff that needs stripping -->
  <xsl:template match="xh:p|xh:div|xh:span|xsh:div|xsh:span">
    <xsl:apply-templates/>
  </xsl:template>

  <!-- was process -->
  <xsl:template match="xh:a[@name]">
    <xsl:element name="dynamicvariable" namespace="http://www.w3.org/1999/xhtml">
      <xsl:attribute name="name">
        <xsl:value-of select="@name"/>
      </xsl:attribute>
    </xsl:element>
  </xsl:template>

  <xsl:template match="xh:a"/>

  <xsl:template match="text()">
    <xsl:value-of select="."/>
  </xsl:template>

</xsl:stylesheet>

Output:

                <ol xmlns="http://www.w3.org/1999/xhtml">
            <li>
                <strong>Review</strong>
                your current available balance. It can be obtained 24 hours a day, 7 days a week through

                any Wells Fargo ATM or by calling
                <dynamicvariable name="Call_Center_Name"/>
                at
                <dynamicvariable name="Phone_Number"/>
                .
            </li>
            <li>
                <strong>Take into account</strong>


                <ul>
                    <li>Your pending transactions and any additional transactions that have not yet been deducted from your available balance, such as checks you have written or upcoming scheduled automatic payments.</li>
                    <li>Any transactions that have been returned because you did not have enough money in your account at that time; they may be resubmitted for payment by the person or party who received the payment from you</li>
                </ul>


            </li>
            <li>
                <strong>Deposit</strong>
                enough money to establish and maintain a positive account balance. A deposit of at least
                <dynamicvariable name="Absolute_Available_Balance"/>
                ,plus
                <dynamicvariable name="Total_Fee"/>
                in fees, would have been required to make your account balance positive at the time we sent this notice.
            </li>
                </ol>






    </text>
</aaa>
查看更多
登录 后发表回答