Как скопировать текст, сгенерированный моим скриптом, в другой раздел моего выходного файла?

#xslt

Вопрос:

Мне нужно скопировать текст, сгенерированный приведенным ниже кодом, в <spine> область в конце моего выходного файла. Как я могу этого добиться?

 <xsl:attribute name="id">
    <xsl:text>ppi</xsl:text>
    <xsl:number format="0000" level="any"/>
</xsl:attribute>
 

Это мой вклад:

 <unit>
   <chapter>
        <exhibit path="chapter001/chapter01_reader01.html"/>
        <exhibit path="chapter001/chapter01_reader02.html"/>
   </chapter>
</unit>
 

Это мой желаемый результат:

 <manifest>
   <item id="ppi0001" href="chapter001/chapter01_reader01.html" media-type="application/xhtml xml"/>
   <item id="ppi0002" href="chapter001/chapter01_reader02.html" media-type="application/xhtml xml"/>
</manifest>
<spine>
   <itemref idref="ppi0001" />
   <itemref idref="ppi0002" />
</spine>
 

Вот мой полный сценарий. Я застрял на той строчке, где написано <!--ID Generated in the "exhibit" template-->

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

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.idpf.org/2007/opf">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    
    <xsl:template match="/">
        
        <xsl:element name="package" namespace="http://www.idpf.org/2007/opf">
            <xsl:attribute name="unique-identifier">pub-id</xsl:attribute>
            <xsl:attribute name="version">3.0</xsl:attribute>
            <manifest>
                <xsl:apply-templates select="//exhibit" />
            </manifest>
            <spine>
                <xsl:element name="itemref">
                    <xsl:attribute name="idref">
                        <!--ID Generated in the "exhibit" template-->
                    </xsl:attribute>
                </xsl:element>
            </spine>
        </xsl:element>     
    </xsl:template>
      
    <xsl:template match="exhibit">
        <xsl:element name="item">
            <xsl:variable name="count" select="position()"/>
            <xsl:attribute name="id">
                <xsl:text>ppi</xsl:text>
                <xsl:number format="0000" level="any"/>
            </xsl:attribute>
            <xsl:attribute name="href">               
                <xsl:value-of select="@path" />
            </xsl:attribute>
            <xsl:attribute name="media-type">               
                <xsl:text>application/xhtml xml</xsl:text>
            </xsl:attribute>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>
 

Спасибо!

Ответ №1:

Вот способ, которым вы могли бы это сделать :

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

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.idpf.org/2007/opf">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    
    <xsl:template match="/">
        <xsl:element name="package" namespace="http://www.idpf.org/2007/opf">
            <xsl:attribute name="unique-identifier">pub-id</xsl:attribute>
            <xsl:attribute name="version">3.0</xsl:attribute>
            <manifest>
                <xsl:apply-templates select="//exhibit" />
            </manifest>
            <spine>
                <xsl:apply-templates select="//exhibit" mode="spine"/>
            </spine>
        </xsl:element>     
    </xsl:template>
      
    <xsl:template match="exhibit">
        <xsl:element name="item">
            <xsl:variable name="count" select="position()"/>
            <xsl:attribute name="id">
                <xsl:text>ppi</xsl:text>
                <xsl:number format="0000" level="any"/>
            </xsl:attribute>
            <xsl:attribute name="href">               
                <xsl:value-of select="@path" />
            </xsl:attribute>
            <xsl:attribute name="media-type">               
                <xsl:text>application/xhtml xml</xsl:text>
            </xsl:attribute>
        </xsl:element>
    </xsl:template>
    
    <xsl:template match="exhibit" mode="spine">
        <xsl:element name="itemref">
            <xsl:variable name="count" select="position()"/>
            <xsl:attribute name="idref">
                <xsl:text>ppi</xsl:text>
                <xsl:number format="0000" level="any"/>
            </xsl:attribute>
        </xsl:element>
    </xsl:template>
    
</xsl:stylesheet>
 

Смотрите, как это работает здесь : https://xsltfiddle.liberty-development.net/6qaHaRT

Комментарии:

1. Это сработало. Большое спасибо! Я действительно ценю это!

Ответ №2:

Поскольку вы повторно используете @id для itemref, я бы использовал это:

 <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns="http://www.idpf.org/2007/opf"
  version="1.0">

  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
  
  <xsl:template match="/">
    <xsl:element name="package" namespace="http://www.idpf.org/2007/opf">
      <xsl:attribute name="unique-identifier">pub-id</xsl:attribute>
      <xsl:attribute name="version">3.0</xsl:attribute>
      <!-- first store the items in a variable -->
      <xsl:variable name="items">
        <!-- if you know the xpath to the exhibit, it is better for performence to make that explicit -->
        <xsl:apply-templates select="unit/chapter/exhibit" />
      </xsl:variable>
      <manifest>
        <!-- then copy those $items into the output -->
        <xsl:copy-of select="$items"/>
      </manifest>
      <spine>
        <!-- then reuse the  $items for creating then itemref's-->
        <xsl:apply-templates select="$items/*/@id" mode="spine"/>
      </spine>
    </xsl:element>     
  </xsl:template>
  
  <xsl:template match="exhibit">
    <xsl:element name="item">
      <xsl:variable name="count" select="position()"/>
      <xsl:attribute name="id">
        <xsl:text>ppi</xsl:text>
        <xsl:number format="0000" level="any"/>
      </xsl:attribute>
      <xsl:attribute name="href">               
        <xsl:value-of select="@path" />
      </xsl:attribute>
      <xsl:attribute name="media-type">               
        <xsl:text>application/xhtml xml</xsl:text>
      </xsl:attribute>
    </xsl:element>
  </xsl:template>
  
  <xsl:template match="@id" mode="spine">
    <xsl:element name="itemref">
      <xsl:attribute name="idref">
        <xsl:value-of select="."/>
      </xsl:attribute>
    </xsl:element>
  </xsl:template>
  
</xsl:stylesheet>