質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

UTF-8

UTF-8は8ビット符号単位の文字符号化形式及び文字符号化スキームです。データ交換方式、ファイル形式としては、一般的にUTF-8が使われる傾向があります。

XSLT

XSLTは、組み立てられた文書を(XML、HTML、そしてプレーンテキストのような)別のフォーマットに変化する為にデザインされたXMLの為の変換用言語です。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Q&A

解決済

2回答

818閲覧

XSLTスタイルシートでの出力

gren5003

総合スコア1

XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

UTF-8

UTF-8は8ビット符号単位の文字符号化形式及び文字符号化スキームです。データ交換方式、ファイル形式としては、一般的にUTF-8が使われる傾向があります。

XSLT

XSLTは、組み立てられた文書を(XML、HTML、そしてプレーンテキストのような)別のフォーマットに変化する為にデザインされたXMLの為の変換用言語です。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

0グッド

0クリップ

投稿2020/07/11 02:55

前提・実現したいこと

XML文書やXSLTスタイルシートを使って、文字などを出力したりしています。
以下のようなXML文書があるとき、表のように、市名・町名・郵便番号を出力させるXSLTスタイルシートを作成したいです。
(見出しは表示しなくていいです。)

AAA bbb 0000000
AAA ccc 1111111
AAA ddd 2222222
EEE fff 3333333
EEE ggg 4444444

該当のソースコード

XML文書

<postcode> <city name="AAA"> <town name="bbb">0000000</town> <town name="ccc">1111111</town> <town name="ddd">2222222</town> </city> <city name="EEE"> <town name="fff">3333333</town> <town name="ggg">4444444</town> </city> </postcode>

試したこと

<?xml version="1.0" ?>

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8" />
<xsl:template match="/">
<xsl:for-each select="postcode">
<xsl:value-of select="city[1]" />
</xsl:for-each>
<xsl:for-each select="postcode">
<xsl:value-of select="city[2]" />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

このようなXSLTスタイルシートを作成したのですが、郵便番号しか出力されませんでした。

補足情報(FW/ツールのバージョンなど)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gemmaro

2020/07/11 03:16

出力の形式は HTML の表でしょうか、それとも空白・改行で区切られたテキストでしょうか
gemmaro

2020/07/11 03:17

`<xsl:output method="text" encoding="UTF-8" />` なので、後者ですね。失礼しました。
guest

回答2

0

XSLT で xsl:for-each を使った時点で、多くの場合、変なことをやってしまっていると考えたほうがよいと思います。

単純に、

  1. town が行になるようなので、ドキュメント ノードから各 town にテンプレートを適用する。
  2. town のテンプレートでは、各列の間にスペースを入れて、行を出す。

とすれば、

xml

1<?xml version="1.0" encoding="UTF-8"?> 2<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 3 <xsl:output method="text" /> 4 <xsl:template match="/"> 5 <xsl:apply-templates select="postcode/city/town" /> 6 </xsl:template> 7 <xsl:template match="town"> 8 <xsl:value-of select="parent::city/@name" /> 9 <xsl:text> </xsl:text> 10 <xsl:value-of select="@name" /> 11 <xsl:text> </xsl:text> 12 <xsl:value-of select="." /> 13 <xsl:text>&#x0A;</xsl:text> 14 </xsl:template> 15</xsl:stylesheet>

となります。

もしも列の数が多くなるようなら、列出力をどこか一カ所で制御したほうがよいでしょう。

なお、20 年以上も前のすり切れた規格である XSLT 1.0 ではなく、XSLT 3.0 を使ってもよいのなら、ほぼ 1 行で済みます:

xml

1<?xml version="1.0" encoding="UTF-8"?> 2<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 3 <xsl:output method="text" /> 4 <xsl:template match="/"> 5 <xsl:text expand-text="yes">{postcode/city/town ! (((parent::city, .) ! @name, .) => string-join(' ')) => string-join('&#x0A;')}&#x0A;</xsl:text> 6 </xsl:template> 7</xsl:stylesheet>

投稿2020/07/13 14:18

編集2020/07/13 14:47
OACleaner

総合スコア63

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

木構造において、根から葉まで、親ノードの情報を渡していくイメージで書くと、以下になります。

ファイル構造

$ exa index.xml main.xsl

ファイル内容

index.xml:

xml

1<?xml version="1.0"?> 2<postcode> 3 <city name="AAA"> 4 <town name="bbb">0000000</town> 5 <town name="ccc">1111111</town> 6 <town name="ddd">2222222</town> 7 </city> 8 <city name="EEE"> 9 <town name="fff">3333333</town> 10 <town name="ggg">4444444</town> 11 </city> 12</postcode>

main.xsl:

xsl

1<?xml version="1.0" ?> 2 3<xsl:stylesheet version="1.0" 4 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 5 6 <xsl:output method="text" encoding="UTF-8" /> 7 8 <xsl:template match="postcode"> 9 <xsl:for-each select="city"> 10 <xsl:call-template name="city"> 11 <xsl:with-param name="city-name"> 12 <xsl:value-of select="@name"/> 13 </xsl:with-param> 14 </xsl:call-template> 15 </xsl:for-each> 16 </xsl:template> 17 18 <xsl:template name="city"> 19 <xsl:param name="city-name"/> 20 21 <xsl:for-each select="town"> 22 <xsl:call-template name="town"> 23 <xsl:with-param name="city-name"> 24 <xsl:value-of select="$city-name"/> 25 </xsl:with-param> 26 <xsl:with-param name="town-name"> 27 <xsl:value-of select="@name"/> 28 </xsl:with-param> 29 </xsl:call-template> 30 </xsl:for-each> 31 </xsl:template> 32 33 <xsl:template name="town"> 34 <xsl:param name="city-name"/> 35 <xsl:param name="town-name"/> 36 37 <xsl:value-of select="$city-name"/> 38 <xsl:text> </xsl:text> 39 <xsl:value-of select="$town-name"/> 40 <xsl:text> </xsl:text> 41 <xsl:value-of select="text()"></xsl:value-of> 42 <xsl:text> 43</xsl:text> 44 </xsl:template> 45 46</xsl:stylesheet>

実行

xsltproc で処理してみた結果が以下になります:

$ xsltproc main.xsl index.xml AAA bbb 0000000 AAA ccc 1111111 AAA ddd 2222222 EEE fff 3333333 EEE ggg 4444444

註釈

xsl:tempalte を函数定義、 xsl:call-template を函数呼び出しのように使っています。
なお、函数の引数定義が xsl:param で、函数への引数渡しが xsl:with-param です。
分量がやや多そうですが、やっていることは単純です。

参考

投稿2020/07/11 03:47

編集2020/07/11 03:57
gemmaro

総合スコア358

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問