动态排序节点并将分隔符放在使用XSLT的位置

时间:2012-02-02 05:33:00

标签: html xml xslt

我有一个HTML文件,我想只使用XSLT转换为XML文档..

我想:

  1. 要保留的所有节点。
  2. 所有元素都已排序。
  3. 代码应该是动态的。
  4. 我在元素之间有一个逗号(,)所以我需要像<dl>,</dl>这样的分隔符来处理它。(不仅逗号某些符号也想保留)
  5. 我有一个巨大的文件所以我想要一个简单的代码来处理所有的html节点。我用xslt解释了我的编码 如果你明白了,请帮助我..

    我的HTML文件是..

    <span id="2102" class="one_biblio">
    <span id="2103" class="one_section-title"><b>Title</b></span>
    <span id="2204" class="one_authors">
        <span id="2205" class="one_author">, <!--here the comma arraives-->
    
            <!-- here the id value misplaced -->
            <span id="2207" class="one_surname">Surname</span>,<!--here the comma arraives-->
            <span id="2206" class="one_given-name">GivenName</span>,<!--here the comma arraives-->
      </span>
    </span>
    <span id="2208" class="one_title">
        <span id="2209" class="one_maintitle">technology</span>
    </span>
    

    我希望输出XML文件为:   这里,属性类值用作元素名称。   以及要排序的元素。   逗号(,)应该在分隔符标记内。

      <biblio id="2102" >
        <section-title id="2103" ><b>Title</b></section-title>
                    <authors id="2204" >
                            <author id="2205" >
                                <dl>,</dl>  <!--here i want like this-->
                                <!-- correrct the id -->
                                <given-name id="2206" >GivenName </given-name><dl>,</dl><!--here i want like this-->
                                <surname id="2207" >Surname</surname><dl>,</dl><!--here i want like this-->
                            </author>
                        </authors>
                        <title id="2208" >
                            <maintitle id="2209" >technology</maintitle>
                        </title>             
              </biblio>
    

    我写的XSLT是..

     <xsl:template match="*[@class]">   
        <xsl:element name="{substring-after(@class, 'mps_')}">
            <xsl:copy-of select="@*[not(name()='class')]"/>
            <xsl:if test="not(current())">
            <xsl:apply-templates>    
                                <xsl:sort select="@id" data-type="number"/>   
            </xsl:apply-templates>   
            </xsl:if>
        </xsl:element>
    </xsl:template> 
    
    Help me.......
    

2 个答案:

答案 0 :(得分:0)

这是一种相当强力的方法,依赖于你知道将用逗号后面的元素的名称。

版本1 - 已知元素名称

<xsl:template match="*[@class]">    
  <!-- copy the computed element name to a variable for ease of use -->
  <xsl:variable name="elementName" select="substring-after(@class, 'one_')"/>

  <xsl:element name="{$elementName}"> 
    <xsl:copy-of select="@*[not(name()='class')]"/> 

    <!-- insert "author" comma -->
    <xsl:if test="$elementName='author'"><dl>,</dl></xsl:if>

    <!-- process contents -->
      <xsl:apply-templates>     
        <xsl:sort select="@id" data-type="number"/>    
      </xsl:apply-templates>

  </xsl:element> 

  <!-- insert 'given-name' and 'surname' commas -->
  <xsl:if test="$elementName='given-name' or $elementName='surname'"><dl>,</dl></xsl:if>

</xsl:template>  

<!-- strip out the 'author' commas where they would normally end up -->
<xsl:template match="text()[normalize-space(.)=','][ancestor-or-self::*[@class='one_author']"/>

如果您无法确定哪些元素将以逗号开头或后跟逗号,那么另一种方法是检查是否存在逗号,然后将其输出到您想要的位置:

版本1 - 元素名称未知     
             

  <xsl:element name="{$elementName}"> 
    <xsl:copy-of select="@*[not(name()='class')]"/> 

    <!-- insert comma if first text child is a comma -->
    <xsl:if test="starts-with(normalize-space(text()[1]), ',')"><dl>,</dl></xsl:if>

    <!-- process contents -->
      <xsl:apply-templates>     
        <xsl:sort select="@id" data-type="number"/>    
      </xsl:apply-templates>
  </xsl:element>         

  <!-- insert comma if the element is immediately followed by a comma -->
  <xsl:if test="normalize-space(following-sibling::text()[1])=','"><dl>,</dl></xsl:if>
</xsl:template>  

<!-- strip out the 'author' commas where they would normally end up -->
<xsl:template match="text()[normalize-space(.)=','][ancestor-or-self::*[@class='one_author']"/>

版本2是否更合适将取决于是否可能包含您不知道的其他任意元素,还取决于没有其他元素以逗号开头或后面跟着您不想保留的逗号。

我希望有所帮助。

答案 1 :(得分:0)

此XSLT 1.0转换

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>

     <xsl:variable name="vrtfPass1">
       <xsl:apply-templates select="/*"/>
     </xsl:variable>

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

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

     <xsl:template match="/">
      <xsl:apply-templates mode="pass2"
           select="ext:node-set($vrtfPass1)/*"/>
     </xsl:template>

     <xsl:template match="*[@class]" mode="pass2">
      <xsl:element name="{substring-after(@class, 'one_')}">
       <xsl:copy-of select="@*[not(name()='class')]"/>
       <xsl:apply-templates>
         <xsl:sort select="@id" data-type="number"/>
       </xsl:apply-templates>
      </xsl:element>
     </xsl:template>

     <xsl:template match=
      "text()
        [../self::span[@class]
        or
         preceding-sibling::node()[1]
                            [self::span[@class]]
         ]
           [contains(., ',')]">
        <xsl:value-of select="substring-before(., ',')"/>
        <dl>,</dl>
        <xsl:value-of select="substring-after(., ',')"/>
      </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档(更正为格式正确!!!):

<span id="2102" class="one_biblio">
    <span id="2103" class="one_section-title">
        <b>Title</b>
    </span>
    <span id="2204" class="one_authors">
        <span id="2205" class="one_author">, 
            <span id="2207" class="one_surname">Surname</span>,
            <span id="2206" class="one_given-name">GivenName</span>,
        </span>
    </span>
    <span id="2208" class="one_title">
        <span id="2209" class="one_maintitle">technology</span>
    </span>
</span>

生成想要的正确结果

<biblio id="2102">
   <span id="2103" class="one_section-title">
      <b>Title</b>
   </span>
   <span id="2204" class="one_authors">
      <span id="2205" class="one_author">
         <dl>,</dl> 

         <span id="2207" class="one_surname">Surname</span>
         <dl>,</dl>

         <span id="2206" class="one_given-name">GivenName</span>
         <dl>,</dl>

      </span>
   </span>
   <span id="2208" class="one_title">
      <span id="2209" class="one_maintitle">technology</span>
   </span>
</biblio>

解释:双程转换。第一遍修正逗号,第二遍修完处理。