xsltによるxml変換で質問です。


xsltを使って、RSSのような複数の記事が連続して収録されているxmlを元に、記事単位でhtmlファイルを生成させることは可能でしょうか。可能であれば方法を教えてください。不可能なのであれば、不可能であることが説明されているURL等を教えてください。

例えば、

<rss>
 <channel>
  <item>
   <title>記事 1</title>
   ...
  </item>
  <item>
   <title>記事 2</title>
   ...
  </item>
  <item>
   <title>記事 3</title>
   ...
  </item>
 </channel>
</rss>

こういうRSS(xml)を入力にして、

-記事1.html
-記事2.html
-記事3.html

を生成するようなことです。1入力1出力の方法はわかりますが、1入力n出力の記述方法がわからないのです。

xsltパーサーはMSXMLを使うつもりですが、どうしても他のパーサーじゃないとダメなのであれば、そのパーサーの使用も検討したいと思います(でもできればMSXMLでやりたい)。

回答の条件
  • 1人3回まで
  • 登録:
  • 終了:2007/04/29 10:23:10
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:mj99 No.3

回答回数138ベストアンサー獲得回数38

ポイント80pt

ほぼズバリの答えがあるようです。

http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=36810&am...

----

個人的に非常に興味がわいたので、

上記URLの情報を参考に「はてな」のrssを分割htmlにしてみた。

以下を『hatena_rss.xsl』として保存。

<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  xmlns:dc="http://purl.org/dc/elements/1.1/">

  <xsl:output method="html" encoding="Shift_JIS"/>

  <msxsl:script language="JScript" implements-prefix="xmlns">
    function putfile(nodeList, item_link)
    {
      var id = item_link.substring(22); // item_linkからhttp://q.hatena.ne.jp以降を拾う
      var filename1 = id + ".xml";      // 分割してローカルにつくるxml名
      var filename2 = id + ".html";     // 分割して作ったxmlをhtmlに変換

      // ファイル操作オブジェクト作成
      var fso = new ActiveXObject("Scripting.FileSystemObject");

      // ファイル書き込み 
      var file = fso.CreateTextFile(filename1); 
      file.Write("&lt;?xml version=\"1.0\" encoding=\"Shift_JIS\"?&gt;");
      file.Write(nodeList.item(0).xml);
      file.close();

      // xmlをhtmlに変換するためmsxslを実行!
      var shell = new ActiveXObject("WScript.Shell");
      shell.Run("cmd /c msxsl " + filename1 +" hatena_rss_item.xsl -o " + filename2, 0, true);

      // xmlは消す
      fso.DeleteFile(filename1);

      // htmlファイル名を返す
      return filename2;
    }
  </msxsl:script> 

  <xsl:template match="/">
    <xsl:apply-templates/>
  </xsl:template> 

  <xsl:template match="channel">
    <html>
    <head>
      <title><xsl:value-of select="title"/></title>
    </head>
    <body>
      <h1><xsl:value-of select="description"/></h1>
      <table border="frame">
        <tr>
         <th>表題</th>
         <th>分類</th>
         <th>作者</th>
        </tr>
        <xsl:apply-templates select="//item"/>
      </table>
    </body>
    </html>
  </xsl:template> 

  <xsl:template match="item">
    <tr>
      <td>
        <xsl:element name="a">
          <xsl:attribute name="href">
            <xsl:value-of select="xmlns:putfile(.,string(link))"/>
          </xsl:attribute>
          <xsl:value-of select="title"/>
        </xsl:element>
      </td>
      <td>
        <xsl:value-of select="category"/>
      </td>
      <td>
        <xsl:value-of select="dc:creator"/>
      </td>
    </tr>
  </xsl:template> 

</xsl:stylesheet> 

以下を『hatena_rss_item.xsl』として保存。

<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/">

  <xsl:output method="html" encoding="Shift_JIS"/>

  <xsl:template match="/">
    <xsl:apply-templates/>
  </xsl:template> 

  <xsl:template match="item">
    <html>
    <head>
      <title><xsl:value-of select="title"/></title>
    </head>
    <body>
      <h1><xsl:value-of select="title"/></h1>
      <table border="frame">
        <tr>
          <th>表題</th>
          <td>
            <xsl:element name="a">
              <xsl:attribute name="href">
                <xsl:value-of select="link"/>
              </xsl:attribute>
              <xsl:value-of select="title"/>
            </xsl:element>
          </td>
        </tr>
        <tr><th>概要</th><td><pre><xsl:value-of select="description"/></pre></td></tr>
        <tr><th>分類</th><td><xsl:value-of select="category"/></td></tr>
        <tr><th>作者</th><td><xsl:value-of select="dc:creator"/></td></tr>
        <tr><th>日付</th><td><xsl:value-of select="pubDate"/></td></tr>
      </table>
    </body>
    </html>
  </xsl:template> 

</xsl:stylesheet> 

・上記2つのファイルを同じフォルダに保存してあるものとします。

・MSXSL.exeにパスが通っているものとします。

・コマンドプロンプトで、上記ファイルを保存してあるフォルダに移動。

・下記コマンド実行!

msxsl http://q.hatena.ne.jp/list?mode=rss hatena_rss.xsl -o hatena_list.html

結果、『hatena_list.html』が入り口のファイルで出来上がり


----

id:naclan

すごいです!


入り口ページのxsl内にスクリプトを書いて、

itemを見つけるたびに内部でさらにmsxslを呼んで

記事単位にファイルを吐いて、

しかもスクリプトの戻り値がそのファイル名で、

入り口ページの記事一覧まで作ってしまう!


質問には書きませんでしたが、

実際には入り口ページも生成させるつもりでしたので、

希望が120%叶った感じです。


まさに解決策です。

ありがとうございました。

2007/04/29 10:21:41

その他の回答2件)

id:TNIOP No.1

回答回数2344ベストアンサー獲得回数58

http://www5b.biglobe.ne.jp/~masai/java/j11.htm

こちらのような感じではいかがでしょうか。

id:naclan

全っっっ然、関係ないです。

びっくりするくらい違います。

2007/04/26 01:04:53
id:felix33 No.2

回答回数343ベストアンサー獲得回数2

このあたりかと。ノードの切り分け

http://www.res-system.com/item/327

id:naclan

1入力1出力の方法はわかりますが、1入力n出力の記述方法がわからないのです。

と書いてるのにー。

2007/04/26 01:06:11
id:mj99 No.3

回答回数138ベストアンサー獲得回数38ここでベストアンサー

ポイント80pt

ほぼズバリの答えがあるようです。

http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=36810&am...

----

個人的に非常に興味がわいたので、

上記URLの情報を参考に「はてな」のrssを分割htmlにしてみた。

以下を『hatena_rss.xsl』として保存。

<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  xmlns:dc="http://purl.org/dc/elements/1.1/">

  <xsl:output method="html" encoding="Shift_JIS"/>

  <msxsl:script language="JScript" implements-prefix="xmlns">
    function putfile(nodeList, item_link)
    {
      var id = item_link.substring(22); // item_linkからhttp://q.hatena.ne.jp以降を拾う
      var filename1 = id + ".xml";      // 分割してローカルにつくるxml名
      var filename2 = id + ".html";     // 分割して作ったxmlをhtmlに変換

      // ファイル操作オブジェクト作成
      var fso = new ActiveXObject("Scripting.FileSystemObject");

      // ファイル書き込み 
      var file = fso.CreateTextFile(filename1); 
      file.Write("&lt;?xml version=\"1.0\" encoding=\"Shift_JIS\"?&gt;");
      file.Write(nodeList.item(0).xml);
      file.close();

      // xmlをhtmlに変換するためmsxslを実行!
      var shell = new ActiveXObject("WScript.Shell");
      shell.Run("cmd /c msxsl " + filename1 +" hatena_rss_item.xsl -o " + filename2, 0, true);

      // xmlは消す
      fso.DeleteFile(filename1);

      // htmlファイル名を返す
      return filename2;
    }
  </msxsl:script> 

  <xsl:template match="/">
    <xsl:apply-templates/>
  </xsl:template> 

  <xsl:template match="channel">
    <html>
    <head>
      <title><xsl:value-of select="title"/></title>
    </head>
    <body>
      <h1><xsl:value-of select="description"/></h1>
      <table border="frame">
        <tr>
         <th>表題</th>
         <th>分類</th>
         <th>作者</th>
        </tr>
        <xsl:apply-templates select="//item"/>
      </table>
    </body>
    </html>
  </xsl:template> 

  <xsl:template match="item">
    <tr>
      <td>
        <xsl:element name="a">
          <xsl:attribute name="href">
            <xsl:value-of select="xmlns:putfile(.,string(link))"/>
          </xsl:attribute>
          <xsl:value-of select="title"/>
        </xsl:element>
      </td>
      <td>
        <xsl:value-of select="category"/>
      </td>
      <td>
        <xsl:value-of select="dc:creator"/>
      </td>
    </tr>
  </xsl:template> 

</xsl:stylesheet> 

以下を『hatena_rss_item.xsl』として保存。

<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/">

  <xsl:output method="html" encoding="Shift_JIS"/>

  <xsl:template match="/">
    <xsl:apply-templates/>
  </xsl:template> 

  <xsl:template match="item">
    <html>
    <head>
      <title><xsl:value-of select="title"/></title>
    </head>
    <body>
      <h1><xsl:value-of select="title"/></h1>
      <table border="frame">
        <tr>
          <th>表題</th>
          <td>
            <xsl:element name="a">
              <xsl:attribute name="href">
                <xsl:value-of select="link"/>
              </xsl:attribute>
              <xsl:value-of select="title"/>
            </xsl:element>
          </td>
        </tr>
        <tr><th>概要</th><td><pre><xsl:value-of select="description"/></pre></td></tr>
        <tr><th>分類</th><td><xsl:value-of select="category"/></td></tr>
        <tr><th>作者</th><td><xsl:value-of select="dc:creator"/></td></tr>
        <tr><th>日付</th><td><xsl:value-of select="pubDate"/></td></tr>
      </table>
    </body>
    </html>
  </xsl:template> 

</xsl:stylesheet> 

・上記2つのファイルを同じフォルダに保存してあるものとします。

・MSXSL.exeにパスが通っているものとします。

・コマンドプロンプトで、上記ファイルを保存してあるフォルダに移動。

・下記コマンド実行!

msxsl http://q.hatena.ne.jp/list?mode=rss hatena_rss.xsl -o hatena_list.html

結果、『hatena_list.html』が入り口のファイルで出来上がり


----

id:naclan

すごいです!


入り口ページのxsl内にスクリプトを書いて、

itemを見つけるたびに内部でさらにmsxslを呼んで

記事単位にファイルを吐いて、

しかもスクリプトの戻り値がそのファイル名で、

入り口ページの記事一覧まで作ってしまう!


質問には書きませんでしたが、

実際には入り口ページも生成させるつもりでしたので、

希望が120%叶った感じです。


まさに解決策です。

ありがとうございました。

2007/04/29 10:21:41

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません