1

<br />XSLT 1.0では、フォーラムでよくある質問は、フラットHTMLを階層XMLに変換する方法でした。これは、多くの場合、タグ内のタグの間にテキストをネストすることになり<p>ます。

同様の問題があり、XSLT 2.0を使用して部分的に解決したと思いますが、これは私にとって新しいアプローチであり、セカンドオピニオンを取得したいと思います。

XHTMLソースはいたるところに<span class="pageStart"></span>散らばっています。それらは、いくつかの異なる親ノードに表示される可能性があります。ノード内の1つのページ開始マーカーと次のページ開始マーカーの間のすべてのノードをラップしたいと思い<page>ます。私が現在持っている解決策は次のとおりです。

<xsl:template match="*[child::span[@class='pageStart']]">
  <xsl:copy>
    <xsl:copy-of select="@*" />
      <xsl:for-each-group select="node()" 
                          group-starting-with="span[@class='pageStart']">
        <page>
          <xsl:apply-templates select="current-group()"/>
        </page>
      </xsl:for-each-group>
  </xsl:copy>
</xsl:template>

これには少なくとも1つの欠陥があります。マーカーの親ノードは、不要な<page>ときに子ノードとして取得されます。他の作品で<div>は、どこかに子ページマーカーがある場合、私が期待する場所に加えて、<page>ノードがの直接の子として作成されます。<div>

テンプレートルールを単純に作成できることを望んでいましたが、<xsl:template match="span[@class='pageStart']">何を試してもcurrent-group()は空のようです。私が試した常識的なアプローチはでした<xsl:for-each-group select="node()" group-starting-with="span[@class='pageStart']">

私が見逃しているこの問題を解決する簡単な方法はありますか?

編集

入力の例を次に示します。

<?xml version="1.0" encoding="UTF-8"?>
<html>
<head></head>
<body>
    <span class="pageStart"/>
    <p>...</p>
    <div>...</div>
    <img />
    <p></p>
    <span class="pageStart"/>
    <div>...</div>
    <span class="pageStart"/>
    <p>...</p>
    <div>
        <span class="pageStart"/>
        <p>...</p>
        <p>...</p>
        <span class="pageStart"/>
        <div>...</div>
        <img/>
    </div>
</body>
</html>

最後の2つのネストされたページがこの問題をより困難にしていると思うので、これを出力として、またはそれに近いものとして取得できれば幸いです。

<?xml version="1.0" encoding="UTF-8"?>
<html>
<head></head>
<body>
    <page>
        <span class="pageStart"/>
        <p>...</p>
        <div>...</div>
        <img />
        <p></p>
    </page>
    <page>
        <span class="pageStart"/>
        <div>...</div>
    </page>
    <page>
        <span class="pageStart"/>
        <p>...</p>
        <div>
            <page>
                <span class="pageStart"/>
                <p>...</p>
                <p>...</p>
            </page>
            <page>
                <span class="pageStart"/>
                <div>...</div>
                <img/>
            </page>
        </div>
    </page>
</body>
</html>
4

1 に答える 1

0

この変換

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="xml" 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="*[span/@class='pageStart']">
  <xsl:copy>
   <xsl:copy-of select="@*"/>
   <xsl:for-each-group select="node()"
       group-starting-with="span[@class='pageStart']">
     <page>
      <xsl:apply-templates select="current-group()"/>
     </page>
   </xsl:for-each-group>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

提供されたXMLドキュメントに適用した場合:

<html>
<head></head>
<body>
    <span class="pageStart"/>
    <p>...</p>
    <div>...</div>
    <img />
    <p></p>
    <span class="pageStart"/>
    <div>...</div>
    <span class="pageStart"/>
    <p>...</p>
    <div>
        <span class="pageStart"/>
        <p>...</p>
        <p>...</p>
        <span class="pageStart"/>
        <div>...</div>
        <img/>
    </div>
</body>
</html>

必要な正しい結果を生成します。

<html>
   <head/>
   <body>
      <page>
         <span class="pageStart"/>
         <p>...</p>
         <div>...</div>
         <img/>
         <p/>
      </page>
      <page>
         <span class="pageStart"/>
         <div>...</div>
      </page>
      <page>
         <span class="pageStart"/>
         <p>...</p>
         <div>
            <page>
               <span class="pageStart"/>
               <p>...</p>
               <p>...</p>
            </page>
            <page>
               <span class="pageStart"/>
               <div>...</div>
               <img/>
            </page>
         </div>
      </page>
   </body>
</html>
于 2011-03-27T18:36:12.707 に答える