How can this XSL be reorganized to use application templates?

Accepting this question about fine XSL , but specifying how I should reorganize this XSL in order to use application templates and / or keys.

I tend to “overuse” for each element to control the context of the source, and I can imagine that using templates can help. Despite the fact that many google-ing, I still do not understand how to manage the context in multiple templates.

In the example below, how can I reduce duplicate XPath segments by refactoring?

    <xsl:template match="/">
    <xsl:element name="Body">
        <xsl:element name="Person">
            <xsl:if     test="/source/dbSrc/srv/v[@name='name']/text()='false'">
                <xsl:element name="PhoneNumber" />
                <xsl:element name="Zip">
                    <xsl:value-of
                        select="/source/req[1]/personal-info/address-info/zip-code" />

                </xsl:element>
            </xsl:if>
            <xsl:if test="/source/dbSrc/srv/v[@name='name']/text()='true'">
                <xsl:element name="PhoneNumber" />
                <xsl:element name="Zip">
                    <xsl:value-of select="/source/req[3]/personal-info/address-info/zip-code" />
                </xsl:element>
            </xsl:if>
        </xsl:element>

</xsl:template>
+3
source share
2 answers

One of the first ways to refactor this code will be as follows:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsl:template match="/">
  <Body>
   <Person>
    <PhoneNumber/>
     <Zip>
       <xsl:apply-templates select=
        "/*/dbSrc/srv/v[@name='name']"/>
     </Zip>
   </Person>
  </Body>
 </xsl:template>

 <xsl:template match="v[@name='name' and .='true']">
   <xsl:value-of select=
   "/*/req[3]/personal-info/address-info/zip-code"/>
 </xsl:template>

 <xsl:template match="v[@name='name' and .='false']">
   <xsl:value-of select=
   "/*/req[1]/personal-info/address-info/zip-code"/>
 </xsl:template>
</xsl:stylesheet>

: xslt.

, - :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsl:variable name="vCond" select=
  "/*/dbSrc/srv/v[@name='name']/text()='true'"/>

 <xsl:variable name="vInd" select=
  "3*$vCond + 1*not($vCond)"/>

 <xsl:template match="/">
  <Body>
   <Person>
    <PhoneNumber/>
     <Zip>
      <xsl:value-of select=
      "/*/req[position()=$vInd]
                /personal-info/address-info/zip-code"/>
     </Zip>
   </Person>
  </Body>
 </xsl:template>
</xsl:stylesheet>

. , /*/dbSrc/srv/v[@name='name']/text() : 'true' 'false'

+1

XSLT 2.0 :

<xsl:template match="/">
    <Body>
        <Person>
          <PhoneNumber/>
          <Zip>
            <xsl:variable name="index" as="xs:integer"
               select="if (/source/dbSrc/srv/v[@name='name']='true') then 3 else 1"/>
            <xsl:value-of select="/source/req[$index]/personal-info/address-info/zip-code"/>
          </Zip>
        </Person>
    </Body>
</xsl:template>

1.0, xsl: , .

; "/text()", .

, , , , , , . , , , : . , , , . "1" "3" , .

+1

Source: https://habr.com/ru/post/1795861/


All Articles