XSL для размещения узлов в предопределенном порядке в XHTML - PullRequest
4 голосов
/ 17 мая 2011

Мне нужно расположить узлы в XHTML в определенном предопределенном порядке, используя XSL, сохранив все остальные преобразования внутри узлов.Входной файл:

<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
  <head> 
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 
  </head> 

  <body class="hresume">

    <div id="sec 1">
      <div>
    text 1
    <span class="summary">position 1</span>
      </div>
    </div>

    <div id="sec 2">
      <div>
    text 2
    <span class="summary">position 2</span>
      </div>
    </div>

  </body> 
</html> 

Преобразование XML:

<?xml version="1.0"?>

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

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

<!-- remove summary -->
<xsl:template match="xhtml:span[@class='summary']"/>

<!-- arrange nodes -->
<do-something match="id('sec 2')"/>
<do-something match="id('sec 1')"/>

</xsl:stylesheet>

Ожидаемый результат - просто поменять узлы "sec 1" и "sec 2" и удалить "итоговые" позиции.Что следует использовать вместо do-something?

Ответы [ 2 ]

3 голосов
/ 18 мая 2011

Это преобразование :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:x="http://www.w3.org/1999/xhtml"
 >
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match=
  "*[x:div[@id='sec 1'] and x:div[@id='sec 2']]">
  <xsl:copy>
   <xsl:apply-templates select="@*"/>

   <xsl:variable name="vDivs" select="x:div"/>

   <xsl:apply-templates select="$vDivs[2]"/>
   <xsl:apply-templates select="$vDivs[1]"/>
  </xsl:copy>
 </xsl:template>
 <xsl:template match="x:span[@class='summary']"/>
</xsl:stylesheet>

при применении к предоставленному XML-документу :

<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    </head>
    <body class="hresume">
        <div id="sec 1">
            <div>     text 1     
                <span class="summary">position 1</span>
            </div>
        </div>
        <div id="sec 2">
            <div>     text 2     
                <span class="summary">position 2</span>
            </div>
        </div>
    </body>
</html>

производит именнотребуемый, правильный результат :

<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
   </head>
   <body class="hresume">
      <div id="sec 2">
         <div>     text 2     
        </div>
      </div>
      <div id="sec 1">
         <div>     text 1     
        </div>
      </div>
   </body>
</html>

Примечание :

  1. Требуемый особый эффект достигается с помощью двух отдельных <xsl:apply-templates> инструкции указаны в нужном порядке.

  2. Требуемое переключение мест между двумя div элементами достигается даже в том случае, если второе предшествовало первому - в результате всегдатот, который был вторым (из двух) в порядке документов, теперь является первым (из двух) в порядке документов.

0 голосов
/ 18 мая 2011

Это решение использует xsl:key и переключает дивы в любом порядке их предоставления:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:x="http://www.w3.org/1999/xhtml"
    >
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:key name="sec" match="x:body/x:div[@id]" use="@id"/>

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

    <xsl:template match="x:div[@id='sec 1']">
        <xsl:element name="{local-name()}" xmlns="http://www.w3.org/1999/xhtml">         
            <xsl:apply-templates select="key('sec','sec 2')/*|key('sec','sec 2')/@*"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="x:div[@id='sec 2']">
        <xsl:element name="{local-name()}" xmlns="http://www.w3.org/1999/xhtml">
            <xsl:apply-templates select="key('sec','sec 1')/*|key('sec','sec 1')/@*"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="x:div[@id='sec 2']/*">
        <xsl:element name="{local-name()}" xmlns="http://www.w3.org/1999/xhtml">
            <xsl:apply-templates select="node()|@*"/>
        </xsl:element>  
    </xsl:template>

    <xsl:template match="x:div[@id='sec 1']/*">
        <xsl:element name="{local-name()}" xmlns="http://www.w3.org/1999/xhtml">
            <xsl:apply-templates select="node()|@*"/>
        </xsl:element>  
    </xsl:template>

    <xsl:template match="x:span[@class='summary']"/>

</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...