Как вызвать значение переменной из одного шаблона в другой шаблон с помощью xslt

Привет, мне нужно вызвать значение переменной из одного шаблона в другой шаблон в файле xsl плагина dita или:

Мой файл Ditamap:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE pubmap
  PUBLIC "urn:pubid:com.sam.doctypes:dita:pubmap" "pubmap.dtd">
<pubmap xml:lang="en-US">
  <pubtitle>
    <mainpubtitle outputclass="book">Sample Word</mainpubtitle>
  </pubtitle>
  <topicref href="topics/topic_1.dita">
    <topicmeta>
      <navtitle>Ram-Files-Raj (RFR)</navtitle>
      <metadata/>
    </topicmeta>
  </topicref>
  <topicref href="topics/topic_2.dita">
    <topicmeta>
      <navtitle>Files-Sampletitle (FST)</navtitle>
      <metadata/>
    </topicmeta>
  </topicref>
</pubmap>

Мой файл theme_1.dita

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE topic
  PUBLIC "urn:pubid:com.sam.doctypes:dita:topic" "topic.dtd">
<topic id="topic_1" xml:lang="en-US" outputclass="Ram-Files-RajRFR"><title>Ram-Files-Raj (RFR)</title></topic>

Мой файл theme_2.dita

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE topic
  PUBLIC "urn:pubid:com.sam.doctypes:dita:topic" "topic.dtd">
<topic id="topic_2" xml:lang="en-US" outputclass="Files-SampletitleFST"><title>Files-Sampletitle (FST)</title></topic>

Мой XSLT-шаблон с необходимой переменной "output-class":

<xsl:template match="*" mode="set-output-class">
  <xsl:param name="default"/>
  <xsl:variable name="output-class">
    <xsl:apply-templates select="." mode="get-output-class"/>
  </xsl:variable>
  <xsl:variable name="draft-revs">
    <!-- If draft is on, add revisions to default class. Simplifies processing in DITA-OT 1.6 and earlier
         that created an extra div or span around revised content, just to hold @class with revs. -->
    <xsl:if test="$DRAFT = 'yes'">
      <xsl:for-each select="*[contains(@class, ' ditaot-d/ditaval-startprop ')]/revprop">
        <xsl:value-of select="@val"/>
        <xsl:text> </xsl:text>
      </xsl:for-each>
    </xsl:if>
  </xsl:variable>
  <xsl:variable name="using-output-class">
    <xsl:choose>
      <xsl:when test="string-length(normalize-space($output-class)) > 0"><xsl:value-of select="$output-class"/></xsl:when>
      <xsl:when test="string-length(normalize-space($default)) > 0"><xsl:value-of select="$default"/></xsl:when>
    </xsl:choose>
    <xsl:if test="$draft-revs != ''">
      <xsl:text> </xsl:text>
      <xsl:value-of select="normalize-space($draft-revs)"/>
    </xsl:if>
  </xsl:variable>
  <xsl:variable name="ancestry">
    <xsl:if test="$PRESERVE-DITA-CLASS = 'yes'">
      <xsl:apply-templates select="." mode="get-element-ancestry"/>
    </xsl:if>
  </xsl:variable>
  <xsl:variable name="outputclass-attribute">
    <xsl:apply-templates select="@outputclass" mode="get-value-for-class"/>
  </xsl:variable>
  <!-- Revised design with DITA-OT 1.5: include class ancestry if requested; 
       combine user output class with element default, giving priority to the user value. -->
  <xsl:if test="string-length(normalize-space(concat($outputclass-attribute, $using-output-class, $ancestry))) > 0">
    <xsl:attribute name="class">
      <xsl:value-of select="$ancestry"/>
      <xsl:if test="string-length(normalize-space($ancestry)) > 0 and 
                    string-length(normalize-space($using-output-class)) > 0"><xsl:text> </xsl:text></xsl:if>
      <xsl:value-of select="normalize-space($using-output-class)"/>
      <xsl:if test="string-length(normalize-space(concat($ancestry, $using-output-class))) > 0 and
                    string-length(normalize-space($outputclass-attribute)) > 0"><xsl:text> </xsl:text></xsl:if>
      <xsl:value-of select="$outputclass-attribute"/>
    </xsl:attribute>
  </xsl:if>
</xsl:template>

из этого вышеприведенного шаблона мне нужно получить переменную «выходной класс» в шаблон ниже:

<xsl:template match="/*[df:class(., 'map/map')]">
    <xsl:param name="doDebug" as="xs:boolean" tunnel="yes" select="false()"/>

    <xsl:variable name="effectiveCoverGraphicUri" as="xs:string">
      <xsl:apply-templates select="." mode="get-cover-graphic-uri"/>
    </xsl:variable>

    <!-- FIXME: Add mode to get effective front cover topic URI so we
         can generate <guide> entry for the cover page. Also provides
         extension point for synthesizing the cover if it's not
         explicit in the map.
    -->

    <xsl:apply-templates select="." mode="report-parameters">
      <xsl:with-param name="effectiveCoverGraphicUri" select="$effectiveCoverGraphicUri" as="xs:string" tunnel="yes"/>
    </xsl:apply-templates>

    <xsl:variable name="graphicMap" as="element()">
      <xsl:apply-templates select="." mode="generate-graphic-map">
        <xsl:with-param name="effectiveCoverGraphicUri" select="$effectiveCoverGraphicUri" as="xs:string" tunnel="yes"/>
        <xsl:with-param name="uplevels" select="$uplevels" as="xs:string" tunnel="yes" />
      </xsl:apply-templates>
    </xsl:variable>

    <xsl:message> + [INFO] Collecting data for index generation, enumeration, etc....</xsl:message>

    <xsl:variable name="collected-data" as="element()">
      <xsl:call-template name="mapdriven:collect-data"/>
    </xsl:variable>

    <xsl:if test="$doDebug">
      <xsl:message> + [DEBUG] Writing file <xsl:sequence select="relpath:newFile($outdir, 'collected-data.xml')"/>...</xsl:message>
      <xsl:result-document href="{relpath:newFile($outdir, 'collected-data.xml')}"
        format="indented-xml"
        >
        <xsl:sequence select="$collected-data"/>
      </xsl:result-document>
    </xsl:if>

    <xsl:result-document href="{relpath:newFile($outdir, 'graphicMap.xml')}" format="graphic-map"
      >
      <xsl:sequence select="$graphicMap"/>
    </xsl:result-document>
    <xsl:call-template name="make-meta-inf"/>
    <xsl:call-template name="make-mimetype"/>

    <xsl:message> + [INFO] Gathering index terms...</xsl:message>

    <xsl:apply-templates select="." mode="generate-content">
      <xsl:with-param name="collected-data" as="element()" select="$collected-data" tunnel="yes"/>
    </xsl:apply-templates>
    <xsl:if test="$epubtrans:isEpub3">
      <xsl:if test="$doDebug">
        <xsl:message> + [DEBUG] generating EPUB3 nav</xsl:message>
      </xsl:if>
      <xsl:apply-templates select="." mode="epubtrans:generate-nav">
        <xsl:with-param name="collected-data" as="element()" select="$collected-data" tunnel="yes"/>
      </xsl:apply-templates>
      <xsl:if test="$doDebug">
        <xsl:message> + [DEBUG] after generate-nav</xsl:message>
      </xsl:if>
    </xsl:if>
    <!-- NOTE: The generate-toc mode is for the EPUB2 toc.ncx, not the HTML toc -->
    <xsl:if test="$epubtrans:isEpub2 or $epubtrans:isDualEpub">
      <xsl:if test="$doDebug">
        <xsl:message> + [DEBUG] generating EPUB2 toc.ncx...</xsl:message>
      </xsl:if>
      <xsl:apply-templates select="." mode="generate-toc">
        <xsl:with-param name="collected-data" as="element()" select="$collected-data" tunnel="yes"/>
      </xsl:apply-templates>
      <xsl:if test="$doDebug">
        <xsl:message> + [DEBUG] after generate-toc</xsl:message>
      </xsl:if>
    </xsl:if>
    <xsl:apply-templates select="." mode="generate-index">
      <xsl:with-param name="collected-data" as="element()" select="$collected-data" tunnel="yes"/>
    </xsl:apply-templates>
    <xsl:if test="$doDebug">
      <xsl:message> + [DEBUG] after generate-index</xsl:message>
    </xsl:if>
    <xsl:apply-templates select="." mode="generate-book-lists">
      <xsl:with-param name="collected-data" as="element()" select="$collected-data" tunnel="yes"/>
    </xsl:apply-templates>
    <xsl:if test="$doDebug">
      <xsl:message> + [DEBUG] after generate-book-lists</xsl:message>
    </xsl:if>
    <xsl:apply-templates select="." mode="generate-opf">
      <xsl:with-param name="graphicMap" as="element()" tunnel="yes" select="$graphicMap"/>
      <xsl:with-param name="collected-data" as="element()" select="$collected-data" tunnel="yes"/>
      <xsl:with-param name="effectiveCoverGraphicUri" select="$effectiveCoverGraphicUri" as="xs:string" tunnel="yes"/>
    </xsl:apply-templates>
    <xsl:if test="$doDebug">
      <xsl:message> + [DEBUG] after generate-opf</xsl:message>
    </xsl:if>
    <xsl:if test="$doDebug">
      <xsl:message> + [DEBUG] Generating graphic copy Ant script...</xsl:message>
    </xsl:if>
    <xsl:apply-templates select="." mode="generate-graphic-copy-ant-script">
      <xsl:with-param name="graphicMap" as="element()" tunnel="yes" select="$graphicMap"/>
    </xsl:apply-templates>
    <xsl:if test="$doDebug">
      <xsl:message> + [DEBUG] after generate-graphic-copy-ant-script</xsl:message>
    </xsl:if>
<xsl:variable name="sample" 
      select="relpath:newFile($outdir, 'sample.xhtml')" 
      as="xs:string"/>
<xsl:result-document href="{$sample}" format="html5">
      <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
          <title>sample</title>
          <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        </head>
        <body>
          <section id="minitoc">
            <ul>
              <li>
                <xsl:choose>
    <xsl:when test="exists($outputclass = 'Ram-Files-RajRFR')">
      <h1><xsl:value-of select="//topic[@outputclass='Ram-Files-RajRFR']"/></h1><hr/>
    </xsl:when>
    <xsl:when test="exists($outputclass = 'Files-SampletitleFST')">
      <h2><xsl:value-of select="//topic[@outputclass='Ram-Files-RajRFR']"/></h2><hr/>
    </xsl:when>
    <xsl:otherwise>

    </xsl:otherwise>
  </xsl:choose></li>
            </ul>
          </section>
        </body>      </html>
    </xsl:result-document>
  </xsl:template>

Пожалуйста, предложите выборку переменной выходного класса в шаблоне '/*[df:class(., 'map/map')]'.

Заранее спасибо.


person User515    schedule 01.06.2018    source источник


Ответы (1)


Шаблон <xsl:template match="*" mode="set-output-class"> возвращает attribute()?. Поэтому, если вы хотите получить этот результат как есть, следующий код в вашем шаблоне <xsl:template match="/*[df:class(., 'map/map')]"> будет работать:

<xsl:variable name="classAttr" as="attribute()?">
    <xsl:apply-templates select="." mode="set-output-class"/>
</xsl:variable>

Или, если вы хотите получить строковое значение:

<xsl:variable name="classValue" as="xs:string" select="string($classAttr)"/>

будет достаточно.

мне нужно значение атрибута выходных классов файла темы для проверки

Я не уверен в преобразовании EPUB. Но следующий код может быть одним из решений.

    <xsl:variable name="topicOutputClasses" as="attribute()*">
        <xsl:for-each select="*[contains(@class,' map/topicref ')][exists(@href)]">
            <xsl:variable name="topicRef" as="element()" select="."/>
            <xsl:variable name="href" as="xs:string" select="$topicRef/@href/string(.)"/>
            <xsl:variable name="topicDoc" as="document-node()" select="document($href,$topicRef)"/>
            <xsl:sequence select="$topicDoc/*[contains(@class,' topic/topic ')]/@outputclass"/>
        </xsl:for-each>
    </xsl:variable>

как сравнить конкретный выходной класс со всеми выходными классами

Изменение предыдущей переменной как xs:string* позволит использовать ее в вашем xsl:when/@test, как и ожидалось.

<xsl:variable name="outputclasse" as="xs:string*">
    <xsl:for-each select="descendant::*[contains(@class,' map/topicref ')][exists(@href)]">
        <xsl:variable name="topicRef" as="element()" select="."/>
        <xsl:variable name="href" as="xs:string" select="$topicRef/@href/string(.)"/>
        <xsl:variable name="topicDoc" as="document-node()" select="document($href,$topicRef)"/>
        <xsl:sequence select="$topicDoc/*[contains(@class,' topic/topic ')]/@outputclass/string(.)"/>
    </xsl:for-each>
</xsl:variable>

Вы можете использовать эту переменную с общим оператором сравнения "=", например:

<xsl:when test="$outputclass = 'Ram-Files-RajRFR'">

он не получает значение внутри h1, используя этот <h1><xsl:value-of select="//topic[@outputclass='Ram-Files-RajRFR']"/></h1>

Если вам удалось получить значение @outputclass из файлов темы, следующий код также будет работать.

[Переменные в шаблоне карты]

<xsl:variable name="outputclasses" as="xs:string*">
    <xsl:for-each select="descendant::*[contains(@class,' map/topicref ')][exists(@href)]">
        <xsl:variable name="topicRef" as="element()" select="."/>
        <xsl:variable name="href" as="xs:string" select="$topicRef/@href/string(.)"/>
        <xsl:variable name="topicDoc" as="document-node()" select="document($href,$topicRef)"/>
        <xsl:if test="exists($topicDoc/*[contains(@class,' topic/topic ')]/@outputclass)">
            <xsl:sequence select="$topicDoc/*[contains(@class,' topic/topic ')]/@outputclass/string(.)"/>
        </xsl:if>
    </xsl:for-each>
</xsl:variable>

<xsl:variable name="topicHrefs" as="xs:string*">
    <xsl:for-each select="descendant::*[contains(@class,' map/topicref ')][exists(@href)]">
        <xsl:variable name="topicRef" as="element()" select="."/>
        <xsl:variable name="href" as="xs:string" select="$topicRef/@href/string(.)"/>
        <xsl:variable name="topicDoc" as="document-node()" select="document($href,$topicRef)"/>
        <xsl:if test="exists($topicDoc/*[contains(@class,' topic/topic ')]/@outputclass)">
            <xsl:sequence select="$href"/>
        </xsl:if>
    </xsl:for-each>
</xsl:variable>

[Получить содержание темы]

<ul>
    <li>
        <xsl:choose>
            <xsl:when test="$outputclasses = 'Ram-Files-RajRFR'">
                <xsl:variable name="index" as="xs:integer" select="index-of($outputclasses,'Ram-Files-RajRFR')"/>
                <xsl:variable name="href" as="xs:string" select="$topicHrefs[$index]"/>
                <xsl:variable name="topicDoc" as="document-node()" select="document($href,.)"/>
                <xsl:value-of select="$topicDoc/*[contains(@class,' topic/topic ')]"/>
            </xsl:when>
        </xsl:choose>
    </li>
</ul>

Этот код является избыточным. Вы можете настроить его по своему усмотрению.

person tmakita    schedule 02.06.2018
comment
Привет @tmakita, используя ваш код, я получаю атрибут выходных классов только файла карты, но мне нужно значение атрибута выходных классов файла темы для просмотра. Я добавил код моей темы и файла карты к вопросу. Не могли бы вы предложить мне. - person User515; 05.06.2018
comment
@ User515 Я не уверен, какую среднюю файловую структуру вы используете. Если вы используете объединенный промежуточный файл (например, PDF2), можно получить элемент темы из темы по ссылке карты. Не могли бы вы уточнить детали вашей трансформации? - person tmakita; 05.06.2018
comment
Мне нужно получить outputclass=Ram-Files-RajRFR, outputclass=Files-SampletitleFST значения outputclass темы из файлов тем внутри шаблона '/*[df:class(., 'map/map')]'. Пожалуйста помогите. спасибо - person User515; 05.06.2018
comment
Спасибо, @tmakita, он извлекает выходные классы, но не могли бы вы предложить мне, как сравнить конкретный выходной класс из всех выходных классов, как отредактировано в последней части вопроса, когда заявление. - person User515; 06.06.2018
comment
Спасибо @tmakita, но он не получает значение внутри h1, используя этот ‹h1›‹xsl:value-of select=//topic[@outputclass='Ram-Files-RajRFR']/›‹/h1› - person User515; 06.06.2018
comment
Большое спасибо @tmakita за терпеливые ответы, все работает нормально. - person User515; 07.06.2018