- PR -

SVGをXSLTで編集したい

1
投稿者投稿内容
itohiro
会議室デビュー日: 2006/09/07
投稿数: 7
投稿日時: 2006-09-07 17:57
はじめまして。itohiroと申します。
初投稿です。XSLT初心者です。
宜しくお願いします。

今、SVG形式のデータをXSLTを使い編集しようとしています。
が思うようにうまくできません。

やりたいことは下記のとおりです。
・<svg>に属性を追加する。
・<image>を<g>で囲む。

問題点が2つあります。
・DTD宣言している行がXSLTパーサに、
<javax.xml.transform.TransformerException: 外部エンティティが見つかりません: "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
と言われる。
・元データの<svg>の属性に"xmlns"があると、<svg>に属性を追加することも、<image>を<g>で囲むことも出来なくなる。

サンプルのソースを以下に載せます。

何かお分かりになる点がございましたらご指摘下さると助かります。
ご教授の程、宜しくお願い致します。

------------------------- 元データ(中略) -----------------------------

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.0//EN' 'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd'>
<svg fill-opacity="1" xmlns:xlink="http://www.w3.org/1999/xlink" color-rendering="auto" color-interpolation="auto" text-rendering="auto" stroke="black" stroke-linecap="square" stroke-miterlimit="10" shape-rendering="auto" stroke-opacity="1" fill="black" stroke-dasharray="none" font-weight="normal" stroke-width="1" xmlns="http://www.w3.org/2000/svg" font-family="&apos;Helvetica&apos;" font-style="normal" stroke-linejoin="miter" font-size="12" stroke-dashoffset="0" image-rendering="auto" width="110.77mm" height="174.98mm" viewBox="0 0 314 496" >
<!--Generated by the Batik Graphics2D SVG Generator-->
<defs id="genericDefs" />
<g>
<g transform="translate(3,18)">
<line transform="translate(0,28)" clip-path="url(#clipPath1)" fill="none" x1="37" x2="35" y1="19.0833" y2="19.0833" stroke-width="0.5" />
<line transform="translate(0,28)" clip-path="url(#clipPath1)" fill="none" x1="37" x2="35" y1="12" y2="12" stroke-width="0.5" />
<image x="5" y="12" transform="translate(52,28)" clip-path="url(#clipPath2)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAT0lEQVR42mM8Y/z/
PwMFgImBQgA3wOQsI4oEOp+gAUCvwDWBaBCfZC/ADCFWM9YwIEUzdQNxBBiAK50Q
bQCudEKSF7ClE5LDAD2dDHwsAABuECEdungTFgAAAABJRU5ErkJggg==" height="16" preserveAspectRatio="none" stroke-width="0.5" stroke-miterlimit="1" />
<image x="21" y="12" transform="translate(52,28)" clip-path="url(#clipPath2)" width="16" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAT0lEQVR42mM8Y/z/
PwMFgImBQgA3wOQsI4oEOp+gAUCvwDWBaBCfZC/ADCFWM9YwIEUzdQNxBBiAK50Q
bQCudEKSF7ClE5LDAD2dDHwsAABuECEdungTFgAAAABJRU5ErkJggg==" height="16" preserveAspectRatio="none" stroke-width="0.5" stroke-miterlimit="1" />
</g>
</g>
</svg>


------------------------- 元データ(中略) -----------------------------


------------------------- XSLT -----------------------------

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


<xsl:param name="width" select="0" />
<xsl:param name="height" select="0" />
<xsl:param name="viewbox_x" select="0" />
<xsl:param name="viewbox_y" select="0" />
<xsl:param name="viewbox_w" select="0" />
<xsl:param name="viewbox_h" select="0" />

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


<xsl:template match="svg">
<!-- xmlns属性をコピーすると属性の追加・更新がうまくいかない -->
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:attribute name="width">
<xsl:value-of select="concat($width, 'mm')" />
</xsl:attribute>
<xsl:attribute name="height">
<xsl:value-of select="concat($height, 'mm')" />
</xsl:attribute>
<xsl:attribute name="viewBox">
<xsl:value-of select="concat($viewbox_x, ' ', $viewbox_y, ' ', $viewbox_w, ' ', $viewbox_h)" />
</xsl:attribute>
<xsl:attribute name="style">overflow:visible</xsl:attribute>
<xsl:attribute name="xml:space">preserve</xsl:attribute>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>


<xsl:template match="*">
<xsl:copy>
<xsl:for-each select="@*">
<xsl:copy />
</xsl:for-each>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>


<xsl:template match="image">
<xsl:element name="g">
<xsl:copy>
<xsl:for-each select="@*">
<xsl:copy />
</xsl:for-each>
<xsl:apply-templates />
</xsl:copy>
</xsl:element>
</xsl:template>


</xsl:stylesheet>


------------------------- XSLT -----------------------------
スフレ
ぬし
会議室デビュー日: 2005/05/27
投稿数: 281
お住まい・勤務地: 東京
投稿日時: 2006-09-07 21:20
Javaでやっているんだと思いますが、どういうプログラムで変換しているかも関係することがあるので、書いたほうがいいです。

引用:

・DTD宣言している行がXSLTパーサに、
<javax.xml.transform.TransformerException: 外部エンティティが見つかりません: "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
と言われる。
・元データの<svg>の属性に"xmlns"があると、<svg>に属性を追加することも、<image>を<g>で囲むことも出来なくなる。



1点目に関しては、自分のコードでXMLパーザを呼ぶようにして、空を返すEntityResolverを使って回避できると思います。

2点目は、itohiroさんのXSLスタイルシートの間違いです。このスタイルシートでは、名前空間なしのsvg要素にしかマッチしません。実際は、入力ドキュメントは名前空間 http://www.w3.org/2000/svg の要素 svg です。
xsl:stylesheet に xmlns:s="http://www.w3.org/2000/svg" を追加し、xsl:template 要素では match="s:svg" に変更することで対応できると思います(image gも同様)。


itohiro
会議室デビュー日: 2006/09/07
投稿数: 7
投稿日時: 2006-09-08 13:12
ご教授頂きありがとうございます。

お教え頂いたテンプレートに変更したところ、
ほぼ意図したものに近い感じになりました。

しかし、<g>と<image>に余計な属性が追加されてしまい、
それが原因でIllustratorで図が正しく表示されません。

XSLTのソースは
<xsl:template match="image">→<xsl:template match="s:image">
に変更しました。

出力した内容は下記のとおりです。
(中略)
<g xmlns:s="http://www.w3.org/2000/svg" xmlns="">
<image xmlns="http://www.w3.org/2000/svg" transform="translate(5,12)" x="" y="" clip-path="" stroke-width="" stroke-miterlimit=""/></g>
<g xmlns:s="http://www.w3.org/2000/svg" xmlns=""><image xmlns="http://www.w3.org/2000/svg" transform="translate(21,12)" x="" y="" clip-path="" stroke-width="" stroke-miterlimit=""/></g>
<g xmlns:s="http://www.w3.org/2000/svg" xmlns=""><image xmlns="http://www.w3.org/2000/svg" transform="translate(37,12)" x="" y="" clip-path="" stroke-width="" stroke-miterlimit=""/></g>

本当は<g>の"xmlns:s"、"xmlns"属性と<image>の"xmlns"は不要な属性です。

何か回避策がありましたらご教授頂きたく願います。
宜しくお願い致します。
MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2006-09-08 13:32
用語の誤り "xmlns:s"、"xmlns"属性
名前空間宣言では、書き方は属性と同じですが、機能は属性ではありません。

ネームスペース URI は、xsl:stylesheet エレメントに exclude-result-prefixes アトリビュートを指定するか、またはリテラル結果エレメントに xsl:exclude-result-prefixes アトリビュートを指定することにより、除外するネームスペースとして指定される。
7.1 エレメントとアトリビュートの生成
http://www.infoteria.com/jp/contents/xml-data/REC-xslt-19991116-jpn.htm#section-Creating-Elements-and-Attributes
文が埋まっているので、読む気が起きないでしょう、一般人は。
itohiro
会議室デビュー日: 2006/09/07
投稿数: 7
投稿日時: 2006-09-08 15:51
早速にご返答頂き、有難うございます。
助かりました。>MMXさん

<g>を生成するところを以下のように変えたらうまくいきました。
<xsl:element name="g" xmlns="http://www.w3.org/2000/svg">

ただ、名前空間は理解してないのでこれからいろいろ調べます。
お教え頂いたinfoteriaのページは、今まで検索には引っ掛かっていましたが、
長いので読んでませんでした。。。
1

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