2016-06-12 101 views
0

我有一個XML文件,我想使用XSLT進行轉換。這個想法是將每個<paragraph/>標籤之前的所有內容放入<p></p>標籤。無法使用XPath訪問文本塊

XML文件:

<section> 
    Hello everyone, I'm 
    <bold>Hackmania</bold> 
    <bold>15</bold> 
    <line/> 
    I am looking for an 
    <highlight>answer</highlight> 
    <paragraph/> 

    Here is an other 
    <bold>paragraph</bold> 
    <highlight>with the same tags</highlight> 
    <paragraph/> 
</section> 

通緝轉換XML:

<section> 
    <p> 
     Hello everyone, I'm 
     <bold>Hackmania</bold> 
     <bold>15</bold> 
     <line/> 
     I am looking for an 
     <highlight>answer</highlight> 
    </p> 
    <p> 
     HHere is an other 
     <bold>paragraph</bold> 
     <highlight>with the same tags</highlight> 
    </p> 
</section> 

這裏是我的XSL文件:提前

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet> 
    <xsl:template match="/"> 
     <section> 
      <xsl:apply-templates/> 
     </section> 
    </xsl:template> 

    <xsl:template match="paragraph"> 
     <xsl:for-each select="."> 
      <p> 
       <xsl:apply-templates select="/*/*[preceding-sibling::paragraph]"/> 
      </p> 
     </xsl:for-each> 

    </xsl:template> 
</xsl:stylesheet> 

感謝您幫助。

回答

1

我會做:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:key name="grpById" match="node()[not(self::paragraph)]" use="generate-id(following-sibling::paragraph[1])" /> 

<xsl:template match="/section"> 
    <xsl:copy> 
     <xsl:for-each select="paragraph"> 
      <p> 
       <xsl:copy-of select="key('grpById', generate-id())"/> 
      </p> 
     </xsl:for-each> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 

如果你可以使用XSLT 2.0,則:

XSLT 2.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 

<xsl:template match="/section"> 
    <xsl:copy> 
     <xsl:for-each-group select="node()" group-ending-with="paragraph"> 
      <p> 
       <xsl:copy-of select="current-group()[not(self::paragraph)]" /> 
      </p> 
     </xsl:for-each-group> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 
+0

感謝您的幫助@ michael.hor257k。 – Hackmania15

0

嘗試這樣:

<xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" encoding="UTF-8"/> 
    <xsl:strip-space elements="*"/> 
    <xsl:template match="@*|node()"> 
      <xsl:copy> 
       <xsl:apply-templates select="node()"/> 
      </xsl:copy> 
    </xsl:template> 
    <xsl:template match="section"> 
     <xsl:apply-templates select="paragraph"/> 
    </xsl:template> 
    <xsl:template match="paragraph"> 
    <xsl:variable name="this" select="." /> 
    <p> 
    <xsl:apply-templates select="preceding-sibling::node()[not(self::paragraph) 
          and generate-id(following-sibling::paragraph) = 
           generate-id($this)]" /> 
    </p> 
    </xsl:template> 
</xsl:stylesheet> 

但要注意如果在最後一段內容上面會失敗。爲了處理該更改的部分模板:

<xsl:template match="section"> 
     <xsl:apply-templates select="paragraph"/> 
     <xsl:apply-templates select="paragraph[last()]/following-sibling::node()"/> 
    </xsl:template>