- PR -

HTML上でXMLファイルの内容を2段階に分けて表示する方法

1
投稿者投稿内容
sampo3
会議室デビュー日: 2007/07/09
投稿数: 1
投稿日時: 2007-07-09 19:56
■list.xml
<list>
<東京>
<name>太郎</name>
<place>渋谷区</place>
<img>tarou.jpg</img>
<info>優しい</info>
</東京>
<東京>
<name>次郎</name>
<place>墨田区</place>
<img>zirou.jpg</img>
<info>江戸っ子</info>
</東京>
<大阪>
<name>三郎</name>
<place>岸和田市</place>
<img>saburou.jpg</img>
<info>怒りっぽい</info>
</大阪>
</list>

このようなXMLファイルを、HTMLファイル上に表示して、XSLを切り替えるサイトを作ろうとしています。

■js.js
function tramsformlists(xmlFile, xslFile, resultNodeID){
var xml, xslt, newDoc;
if(document.all){
xml = new ActiveXObject("Microsoft.XMLDOM");
xslt = new ActiveXObject("Microsoft.XMLDOM");
}
else {
xml = document.implementation.createDocument("", "", null);
xslt = document.implementation.createDocument("", "", null);
}
xml.async = false;
xslt.async = false;
xml.load(xmlFile);
xslt.load(xslFile);
if(document.all){
document.getElementById(resultNodeID).innerHTML = xml.transformNode(xslt);
}
else {
var xsltp = new XSLTProcessor();
xsltp.importStylesheet(xslt);
newDoc = xsltp.transformToFragment(xml, window.document);
document.getElementById('ShowXML').innerHTML = "";
document.getElementById('ShowXML').appendChild(newDoc);
}
}

■zenkoku.xsl
<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet version="1.0" xmlns:xsl="&#8203;http://www.w3.org/1999/XSL/Transform">&#8203;
<xsl:template match="list">
<xsl:apply-templates select="東京"/>
<xsl:apply-templates select="大阪"/>
</xsl:template>
<xsl:template match="東京">
<div>
<xsl:value-of select="name"/>
<xsl:value-of select="day"/>
<xsl:value-of select="place"/>
<INPUT type="button" value="詳細"/>
</div>
</xsl:template>
<xsl:template match="大阪">
<div>
<xsl:value-of select="name"/>
<xsl:value-of select="day"/>
<xsl:value-of select="place"/>
<INPUT type="button" value="詳細"/>
</div>
</xsl:template>
</xsl:stylesheet>

■tokyo.xsl
<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet version="1.0" xmlns:xsl="&#8203;http://www.w3.org/1999/XSL/Transform">&#8203;
<xsl:template match="list">
<xsl:apply-templates select="東京"/>
</xsl:template>
<xsl:template match="東京">
<div>
<xsl:value-of select="name"/>
<xsl:value-of select="day"/>
<xsl:value-of select="place"/>
<INPUT type="button" value="詳細"/>
</div>
</xsl:template>
</xsl:stylesheet>

■osaka.xsl
<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet version="1.0" xmlns:xsl="&#8203;http://www.w3.org/1999/XSL/Transform">&#8203;
<xsl:template match="list">
<xsl:apply-templates select="大阪"/>
</xsl:template>
<xsl:template match="大阪">
<div>
<xsl:value-of select="./name"/>
<xsl:value-of select="./day"/>
<xsl:value-of select="./place"/>
<INPUT type="button" value="詳細"/>
</div>
</xsl:template>
</xsl:stylesheet>

■list.html
<?xml version="1.0" encoding="Shift_JIS"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"&#8203;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">&#8203;
<html xmlns="&#8203;http://www.w3.org/1999/xhtml"&#8203; xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=Shift_JIS" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<script type="text/javascript" src="js.js"></script>
<title>リスト</title>
</head>
<body onload="tramsformlists('list.xml', 'zenkoku.xsl', 'ShowXML')">
<div>
<span onclick="tramsformlists('list.xml', 'zenkoku.xsl', 'ShowXML')">全国</span>
<span onclick="tramsformlists('list.xml', 'tokyo.xsl', 'ShowXML')">東京</span>
<span onclick="tramsformlists('list.xml', 'osaka.xsl', 'ShowXML')">大阪</span>
</div>
<div id="ShowXML"></div>
<div>□■領域X■□</div>
</body>
</html>

こんな感じで、全国⇔東京⇔大阪と、XSLを切り替えて表示させることはできたのですが、表示される[詳細]ボタンをクリックすると、そこに対応する<img>、<info>をHTML上の別の領域(この場合□■領域X■□と書いてあるDIV)に表示させたいのです。
実際のファイルではXMLファイルの内容ももっと数が多く、とりあえず<div id="ShowXML">に<name>と<place>だけを表示させておきたいので、このようなレイアウトが良いと思ったのですが、こんな2段階で表示させるという方法は無いのでしょうか。

もし無いとすれば、どのような方向性でやればいいのか…。
初心者でして、javascriptファイルはコピペで作ったので、ちょっと変かもしれません。
どなたか教えていただけたらと思います。
会議室デビュー日: 2007/08/09
投稿数: 4
投稿日時: 2007-08-12 03:14
2段階で表示させること自体は、問題なくできるようです。
1)□■領域X■□のdivにidを追加。list.html
2)「詳細」ボタンが押された時の動作を設定。tokyo.xsl
3)infoとimgを表示するためのスタイルシートを作成。tokyo2.xsl
以下にファイルを貼り付けましたが、東京のデータについてのみ動作します。

ただ、私の作ったものは、たとえば、「東京」を選んだ後に「太郎」の「詳細」ボタンを押すと、「太郎」と「次郎」の両方の詳細情報が表示されてしまいます。おそらく、お望みの動作は、「太郎」の「詳細」ボタンを押したら、「太郎」の詳細情報のみが表示されるというものだと思います。これを実現しようとすると、tokyo2.xslを適用する際に、今回は「太郎」の情報を引き出せ、今回は「次郎」だ、とjavascriptから教えてやらないといけません。それは、パラメータを使うことによって可能であり、私のコードのコメントアウトした部分をはずせば、一例として、「太郎」データだけを出力するようになります。とりあえず「太郎」決めうちですが、最終的には、transformlists関数の引数として個人名を渡すようにし、そのためにはinputのonclickの式に個人名が反映されるようにしないといけません。

また、「東京」を選択し、「太郎」の詳細を表示させた後に、「大阪」を選ぶと、「三郎」が一段目に表示され、その下には「太郎」の詳細表示が残ったままになってしまいます。これは、ユーザーから見てあまりかっこよくないと思います。

私も大して経験があるわけではないのですが、この件は、スタイルシートを中心に考えるより、javascriptにすべての処理をさせたほうがすっきり行くのではないかと思います。DOM(Document Object Model)を使ってjavascriptからxmlの要素を取り出して、処理するということです。



-----list.html-------
<?xml version="1.0" encoding="Shift_JIS"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=Shift_JIS" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<script type="text/javascript" src="js.js"></script>
<title>リスト</title>
</head>
<body onload="tramsformlists('list.xml', 'zenkoku.xsl', 'ShowXML')">
<div>
<span onclick="tramsformlists('list.xml', 'zenkoku.xsl', 'ShowXML')">全国</span>
<span onclick="tramsformlists('list.xml', 'tokyo.xsl', 'ShowXML')">東京</span>
<span onclick="tramsformlists('list.xml', 'osaka.xsl', 'ShowXML')">大阪</span>
</div>
<div id="ShowXML"></div>
<div id="X">□■領域X■□</div> //idを追加
</body>
</html>
-----js.js--------
function tramsformlists(xmlFile, xslFile, resultNodeID){
var xml, xslt, newDoc;
if(document.all){
xml = new ActiveXObject("Microsoft.XMLDOM");
xslt = new ActiveXObject("Microsoft.XMLDOM");
}
else {
xml = document.implementation.createDocument("", "", null);
xslt = document.implementation.createDocument("", "", null);
}
xml.async = false;
xslt.async = false;
xml.load(xmlFile);
xslt.load(xslFile);
if(document.all){
document.getElementById(resultNodeID).innerHTML = xml.transformNode(xslt);
}
else {
var xsltp = new XSLTProcessor();
xsltp.importStylesheet(xslt);
//xsltp.setParameter(null, "param", "太郎"); //パラメータ(「太郎」に決めうちだが、本来はtransformlistsの引数として渡すなどしたい。)
newDoc = xsltp.transformToFragment(xml, window.document);
document.getElementById(resultNodeID).innerHTML = ""; //'ShowXML'をresultNodeIDへ変更
document.getElementById(resultNodeID).appendChild(newDoc);
}
}
-----tokyo.xsl--------
<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="list">
<xsl:apply-templates select="東京"/>
</xsl:template>
<xsl:template match="東京">
<div>
<xsl:value-of select="name"/>
<xsl:value-of select="day"/>
<xsl:value-of select="place"/>
<INPUT type="button" value="詳細" onclick="tramsformlists('list.xml', 'tokyo2.xsl', 'X')"/> // onclickを追加
</div>
</xsl:template>
</xsl:stylesheet>
-----tokyo2.xsl-------
<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- <xsl:param name="param"/> --> <!-- パラメータを受け取る -->
<xsl:template match="list">
<xsl:apply-templates select="東京"/>
</xsl:template>
<xsl:template match="東京">
<!-- <xsl:if test="name = $param"> --> <!-- パラメータの値とnameの値とが等しかったら。。。-->
<div>
<xsl:element name="img">
<xsl:attribute name="src">
<xsl:value-of select="img"/>
</xsl:attribute>
</xsl:element>
<xsl:value-of select="info"/>
</div>
<!-- </xsl:if> -->
</xsl:template>
</xsl:stylesheet>
--------list.xml --------
<?xml version="1.0" encoding="Shift_JIS"?>
<list>
<東京>
<name>太郎</name>
<place>渋谷区</place>
<img>http://www.atmarkit.co.jp/bbs/phpBB/images/reply.gif</img>
<info>優しい</info>
</東京>
<東京>
<name>次郎</name>
<place>墨田区</place>
<img>http://www.atmarkit.co.jp/bbs/phpBB/images/new_topic.gif</img>
<info>江戸っ子</info>
</東京>
<大阪>
<name>三郎</name>
<place>岸和田市</place>
<img>saburou.jpg</img>
<info>怒りっぽい</info>
</大阪>
</list>
1

スキルアップ/キャリアアップ(JOB@IT)