001/* 002 * Copyright (c) 2009 The openGion Project. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 013 * either express or implied. See the License for the specific language 014 * governing permissions and limitations under the License. 015 */ 016package org.opengion.fukurou.xml; 017 018import org.opengion.fukurou.system.OgRuntimeException ; // 6.4.2.0 (2016/01/29) 019import org.opengion.fukurou.system.Closer ; 020import org.opengion.fukurou.system.DateSet; // 6.4.2.0 (2016/01/29) 021import org.opengion.fukurou.system.LogWriter; 022import org.opengion.fukurou.util.HybsEntry ; 023import org.opengion.fukurou.util.FileUtil ; 024import org.opengion.fukurou.util.StringUtil ; 025import static org.opengion.fukurou.system.HybsConst.CR; // 6.1.0.0 (2014/12/26) refactoring 026import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE; // 6.1.0.0 (2014/12/26) refactoring 027 028import java.io.Reader; 029import java.io.Writer; 030import java.io.File; 031import java.io.IOException; 032import java.io.StringReader; 033 034import javax.xml.transform.TransformerException; 035import javax.xml.transform.TransformerConfigurationException; 036import javax.xml.transform.TransformerFactory; 037import javax.xml.transform.Transformer; 038import javax.xml.transform.stream.StreamSource; 039import javax.xml.transform.stream.StreamResult; 040import javax.xml.transform.ErrorListener; // 6.4.0.2 (2015/12/11) 041 042/** 043 * XML 入力ファイルに、XSL 入力ファイルを適用して、 XSLT変換を行います。 044 * 結果は、XML 出力ファイルにセーブします。 045 * 各ファイルの代わりに、Writer,Reader を設定することも可能です。 046 * 047 * このパーサーでは、内部で実行中の入力ファイル情報を パラメータとして設定できます。 048 * useFileInfo( true ) とセットすると、以下の4項目が内部的にセットされます。 049 * ただし、この設定が可能なのは、XML 入力ファイルに、Reader ではなく、ファイル名を 050 * 渡した場合のみです。ストリームの場合は、各種情報は取れません。 051 * 052 * 入力ファイル(inXMLのフルパス) : FILEPATH (例: G:\webapps\gf\jsp\DOC10\query.jsp) 053 * 入力親フォルダ(inXMLの親フォルダ) : ADDRESS (例: DOC10) 054 * 入力ファイル(inXMLのファイル名) : FILENAME (例: query.jsp) 055 * 入力ファイル(inXMLの更新日付 ) : MODIFIED (例: yyyyMMddHHmmss形式) 056 * 057 * xsl ファイルでは、パラメータ は、xsl:param で宣言し、xsl:value-of で取り出します。 058 * <xsl:param name="ADDRESS" select="" /> と宣言しておき、必要な箇所で 059 * <xsl:value-of select="$ADDRESS" /> とすれば、取得できます。 060 * 061 * String inXSTL = "inXSLfile.xsl" ; // 入力XSLファイル 062 * String outFile = "outXMLfile.xml" ; // 出力XMLファイル 063 * String inXML = "inXMLfile.xml" ; // 入力XMLファイル 064 * 065 * XSLT xslt = new XSLT(); 066 * xslt.setXslFile( inXSTL ); 067 * xslt.setOutFile( outFile,false ); 068 * 069 * xslt.transform( inXML ); 070 * 071 * @version 4.0 072 * @author Kazuhiko Hasegawa 073 * @since JDK5.0, 074 */ 075public class XSLT { 076 /** 初期 ENCODE 名 {@value} */ 077 public static final String ENCODE = "UTF-8" ; 078 079 private Transformer transformer ; 080 081 private String encode = ENCODE; 082 private String xmlFile ; 083 private String xslFile ; 084 private String outFile ; 085 private Reader xslReader ; 086 private Writer outWriter ; 087 private HybsEntry[] paramEntry ; 088 private boolean isFileInfo ; 089 private boolean isErrClose = true; 090 private boolean isErrXmlIn ; // useErrXmlIn ⇒ isErrXmlIn 変更 091 private boolean isInclude = true; // 4.2.3.0 (2008/05/26) 092 private StreamResult result ; 093 094 private String realPath ; // 5.7.6.2 (2014/05/16) 新規追加 095 private String debugMsg ; // 5.6.7.1 (2013/08/09) デバッグ用 096 097 /** 098 * 入力XSLファイルを、指定します。 099 * 100 * @param file 入力XSLファイル 101 * @see #setXslFile( Reader ) 102 */ 103 public void setXslFile( final String file ) { 104 xslFile = file; 105 setXslFile( FileUtil.getBufferedReader( new File( xslFile ),encode ) ); 106 } 107 108 /** 109 * 入力XSLリーダーを、指定します。 110 * 111 * @param reader 入力XSLリーダー 112 * @see #setXslFile( String ) 113 */ 114 public void setXslFile( final Reader reader ) { 115 transformer = null; 116 xslReader = reader; 117 } 118 119 /** 120 * 結果XML ファイル名と、そのオープン方法を指定します。 121 * 結果XML ファイルを、追記する(append=true)か新規作成する(append=false)か指定します。 122 * なお、結果XML ファイル(outFile) を指定しない(=null)か、特別な名称 "System.out" 123 * 文字列を渡すと、標準出力に 結果を出力します。 124 * 125 * @param file 出力ファイル名(null または、"System.out" 文字列時は、標準出力) 126 * @param append [true]追記する/false:新規作成する] 127 */ 128 public void setOutFile( final String file,final boolean append ) { 129 outFile = file ; 130 setOutFile( FileUtil.getPrintWriter( new File( outFile ),encode,append ) ); 131 } 132 133 /** 134 * 結果XML データを出力する、Writer を指定します。 135 * ファイル、標準出力、JSPWriter など、必要に応じて Writer を作成してください。 136 * 標準出力(System.out)の場合は、NonClosePrintWriter クラスなどの非close()処理系を、 137 * JSPWriterの場合は、NonFlushPrintWriter クラスなどの非flush()、close()処理系を、 138 * 使用してください。 139 * 140 * @param writer 出力するWriter 141 */ 142 public void setOutFile( final Writer writer ) { 143 Closer.ioClose( outWriter ); 144 outWriter = writer ; 145 result = new StreamResult( outWriter ); 146 } 147 148 /** 149 * 結果XML ライターに、指定のデータを書き出します。 150 * 151 * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs) 152 * 153 * @param outData 書き出すデータ 154 */ 155 public void setOutData( final String outData ) { 156 if( outData != null && outData.length() > 0 ) { 157 // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs) 158 if( outWriter == null ) { 159 final String errMsg = "#setOutFile(Writer)を先に実行しておいてください。" + CR 160 + " outData =" + outData + CR; 161 throw new OgRuntimeException( errMsg ); 162 } 163 164 try { 165 outWriter.write( outData ); 166 outWriter.write( CR ); 167 } 168 catch( final IOException ex ) { 169 final String errMsg = "ライターにデータ登録を失敗しました。" + CR 170 + ex.getMessage() ; 171 close(); 172 throw new OgRuntimeException( errMsg,ex ); 173 } 174 } 175 } 176 177 /** 178 * XML ファイルをXSLT変換します。 179 * XML 入力ファイルに、XSL 入力ファイルを適用して、 XSLT変換を行います。 180 * 結果は、XML ファイルにセーブします。 181 * 拡張子が『.jsp』で、かつ、isInclude=true の場合、jsp:directive.include 処理を行います。 182 * 183 * @og.rev 4.2.3.0 (2008/05/26) jsp:directive.include 処理の実施可否を引数指定します。 184 * @og.rev 5.2.1.0 (2010/10/01) JspIncludeReader#getString の第3引数を廃止 185 * @og.rev 5.6.7.1 (2013/08/09) デバッグ用に、ファイルリストを取得しておきます。 186 * @og.rev 5.7.6.2 (2014/05/16) #transform( String , boolean ) 廃止。realPath 追加 187 * 188 * @param file 入力XMLファイル 189 */ 190 public void transform( final String file ) { 191 xmlFile = file; 192 193 if( xmlFile.endsWith( ".jsp" ) && isInclude ) { 194 // 5.6.7.1 (2013/08/09) デバッグ用に、ファイルリストを取得しておきます。 195 final JspIncludeReader incReader = new JspIncludeReader(); 196 incReader.setRealPath( realPath ); // 5.7.6.2 (2014/05/16) realPath 追加 197 debugMsg = incReader.getIncludeFiles(); 198 199 final String incData = incReader.getString( new File( xmlFile ),encode ); // 5.2.1.0 (2010/10/01) 200 transform( new StringReader( incData ) ); 201 } 202 else { 203 transform( FileUtil.getBufferedReader( new File( xmlFile ),encode ) ); 204 } 205 } 206 207 /** 208 * XML ファイルをXSLT変換します。 209 * XML 入力リーダーに、XSL 入力リーダーを適用して、 XSLT変換を行います。 210 * 結果は、XML ライターに書き出します。 211 * この処理の終了後に、入力XML リーダー は、close() されます。 212 * 213 * @og.rev 5.6.5.2 (2013/06/21) エラーメッセージが判りにくいので、追記します。 214 * @og.rev 5.6.7.1 (2013/08/09) デバッグ用に、ファイルリストを出力します。 215 * @og.rev 6.4.0.2 (2015/12/11) Transformer のエラーを、より詳細に出力します。 216 * 217 * @param xmlReader 入力XML リーダー 218 * @see #transform( String ) 219 */ 220 public void transform( final Reader xmlReader ) { 221 HybsEntry[] entry = null; 222 223 // transformer は使いまわしますが、ErrorListener は、Reader 毎に再作成します。 224 final ErrorListener errListener = new HybsErrorListener(); // 6.4.0.2 (2015/12/11) 225 try { 226 if( transformer == null ) { 227 init( errListener ); // 6.4.0.2 (2015/12/11) 228 } 229 else { 230 transformer.reset(); 231 transformer.setErrorListener( errListener ); // 6.4.0.2 (2015/12/11) 232 } 233 234 // 入力XMLファイルのファイル情報を設定します。 235 if( isFileInfo && xmlFile != null ) { 236 entry = getXmlParameter( xmlFile ); 237 parameterSet( transformer,entry ); 238 } 239 xmlFile = null ; 240 241 // 入力XMLリーダーからStreamSourceを作る 242 final StreamSource data = new StreamSource( xmlReader ); 243 244 transformer.transform( data,result ); 245 } 246 catch( final TransformerException ex ) { 247 // 5.7.3.0 (2014/02/07) エラー情報をもう少し詳細に取得します。 248 // final String errMsg = ex.getMessageAndLocation() ; 249 final String errMsg = errListener.toString(); // 6.4.0.2 (2015/12/11) さらに詳細に出します。 250 251 final StringBuilder errBuf = new StringBuilder( BUFFER_MIDDLE ) 252 .append( "=====================================================" ).append( CR ) 253 .append( "XML-XSLT 変換に失敗しました。" ).append( CR ) 254 .append( errMsg ); 255 256 // 6.3.1.0 (2015/06/28) デバッグ用メッセージを出力します。 257 if( debugMsg != null && debugMsg.length() > 0 ) { 258 errBuf.append( CR ).append( debugMsg ); 259 } 260 261 // 5.6.5.2 (2013/06/21) エラーメッセージが判りにくいので、追記します。 262 if( errMsg.indexOf( "プロローグにはコンテンツを指定できません" ) >= 0 ) { 263 errBuf.append( CR ).append( "\t(UTF-8変換時に、BOMが付くとこのエラーが出ます。BOMを外してみてください。)" ); 264 } 265 266 // 5.6.7.1 (2013/08/09) デバッグ用に、ファイルリストを出力します。 267 if( errMsg.indexOf( "で終了する必要があります" ) >= 0 ) { 268 errBuf.append( CR ).append( "\t(不整合は、includeファイルの可能性があります。)" ); 269 } 270 errBuf.append( CR ); 271 272 if( isErrXmlIn ) { setOutData( toXmlRow( entry, ex ) ); } 273 274 if( isErrClose ) { close(); } 275 throw new OgRuntimeException( errBuf.toString(),ex ); 276 } 277 finally { 278 Closer.ioClose( xmlReader ); 279 } 280 } 281 282 /** 283 * Transformer オブジェクトに対して、Parameter を設定します。 284 * 285 * 指定されたパラメーターキーは、xsl ファイルでは、xsl:param で宣言し、 286 * xsl:value-of で取り出します。 287 * <xsl:param name="ADDRESS" select="" /> と宣言しておき、必要な箇所で 288 * <xsl:value-of select="$ADDRESS" /> とすれば、取得できます。 289 * 290 * @param entry HybsEntry配列(可変長引数) 291 */ 292 public void setParamEntry( final HybsEntry... entry ) { 293 if( entry != null && entry.length > 0 ) { // 6.1.1.0 (2015/01/17) 可変長引数でもnullは来る。 294 paramEntry = new HybsEntry[entry.length]; 295 System.arraycopy( entry,0,paramEntry,0,entry.length ); 296 } 297 } 298 299 /** 300 * transform 処理中にエラーが発生した場合に、出力ファイルを閉じるかどうかを指定します。 301 * 302 * 処理途中でエラーが発生した場合に、そこで処理を中断するか、それとも、 303 * 無視して、さらに処理を進めるかを指定することが可能です。 304 * 継続して処理を進めたい場合は、出力ファイルを閉じないため、false を 305 * 設定します。ただし、エラー時には、RuntimeException は throw されます。 306 * 初期値は、true(閉じる)です。 307 * 308 * @param flag エラー時クローズ [true:閉じる/false:閉じない] 309 */ 310 public void errClose( final boolean flag ) { 311 isErrClose = flag ; 312 } 313 314 /** 315 * transform 処理中エラーを、出力ファイルに、XML形式でエラーを追記するかどうかを指定します。 316 * 317 * 処理途中でエラーが発生した場合に、ログだけではなく、結果XMLファイルに、 318 * エラー内容や、エラーファイルなどを埋め込むと、XMLファイルとしてDB登録や、 319 * その他集計等に使えます。 320 * 今は、GE70 スキーマ形式のファイルしか作成できません。 321 * これは、#errClose( boolean ) メソッドと共に使用すると効果的です。 322 * つまり、errClose = false; にして、エラー時でも出力ファイルを閉じずに、 323 * 処理を続ける事で、エラーメッセージもXMLファイルとして蓄積できます。 324 * 初期値は、false(使用しない)です。 325 * 326 * @param flag エラー時XML形式 [false:使用しない/true:使用する] 327 */ 328 public void useErrXmlIn( final boolean flag ) { 329 isErrXmlIn = flag ; 330 } 331 332 /** 333 * jsp:directive.include 発見時に、そのファイルを INCLUDE するかを指定するかどうかを指定します(初期値:true:使用する) 334 * 335 * 引数の処理対象ファイル(transformの引数ファイル)が、『.jsp』の場合、 336 * jsp:directive.include 発見時に、そのファイルを INCLUDE するかを指定するか 337 * どうかを指定します。 338 * インクルードされたファイルとあわせて、正規のXML にならないと、パーサー 339 * エラーが発生します。 340 * JSPソース解析を行うには、INCLUDE ファイルも考慮しないと正確な結果を 341 * 得られませんが、INCLUDE 先のファイルまで合わせる必要があるため、 342 * 場合によっては、INCLUDEファイルを無視しなければならないケースがあります。 343 * 初期値は、true(使用する)です。 344 * 345 * @param flag エラー時XML形式 [false:使用しない/true:使用する] 346 */ 347 public void jspInclude( final boolean flag ) { 348 isInclude = flag ; 349 } 350 351 /** 352 * jspInclude=true 時に、/jsp/common/** 等の include ファイルが存在しない場合の共有取得場所を指定します。 353 * 354 * 引数の処理対象ファイル(transformの引数ファイル)が、『.jsp』で、かつ、jspInclude=true の場合、 355 * そのファイルを INCLUDE するのですが、/jsp/common/** 等の include ファイルは、 356 * エンジン共通として、jspCommon6.x.x.x.jar で提供しています。 357 * 従来は、処理対象jspの相対パスで、../../../gf/jsp/commom/** を取り込んでいましたが、 358 * Tomcat起動フォルダ以外のシステムのJSPチェックなどを行う場合は、gf フォルダが存在しない 359 * ケースがあります。 360 * そこで、確実にgf が存在する、処理をキックしている環境の gf を使用するように変更します。 361 * その環境とは、つまり、エンジン内部変数の REAL_PATH ですが、jsp などが実行していないと取得できません。 362 * 363 * @param path /jsp/common/** 等の include ファイルの共有取得場所 364 */ 365 public void setRealPath( final String path ) { 366 realPath = path ; 367 } 368 369 /** 370 * 入力XSLファイルのストリームを閉じます。 371 * 372 * @og.rev 5.6.7.1 (2013/08/09) includeしたファイルのキャッシュをクリアします。 373 */ 374 public void close() { 375 Closer.ioClose( outWriter ); 376 377 // 5.6.7.1 (2013/08/09) includeしたファイルのキャッシュをクリア 378 JspIncludeReader.cacheClear(); 379 } 380 381 /** 382 * XML ファイルをXSLT変換します。 383 * XML 入力ファイルに、XSL 入力ファイルを適用して、 XSLT変換を行います。 384 * 結果は、XML ファイルにセーブします。 385 * なお、結果XML ファイル(outFile) に、特別な名称 "System.out" 文字列を渡すと、 386 * 標準出力に 結果を出力します。 387 * 388 * @og.rev 5.6.7.1 (2013/08/09) includeしたファイルのキャッシュをクリアします。 389 * @og.rev 6.4.0.2 (2015/12/11) Transformer のエラーを、より詳細に出力します。 390 * 391 * @param errListener ErrorListenerオブジェクト 392 */ 393 private void init( final ErrorListener errListener ) { 394 try { 395 // xsl属性からStreamSourceを作る 396 final StreamSource style = new StreamSource( xslReader ); 397 398 // Transformerを作り、XMLを変換する 399 final TransformerFactory tFactory = TransformerFactory.newInstance(); 400 401 // 6.4.0.2 (2015/12/11) Transformer のエラーを、より詳細に出力します。 402 tFactory.setErrorListener( errListener ); 403 404 transformer = tFactory.newTransformer( style ); 405 // 6.4.0.2 (2015/12/11) Transformer のエラーを、より詳細に出力します。 406 transformer.setErrorListener( errListener ); 407 408 parameterSet( transformer,paramEntry ); 409 410 // 5.6.7.1 (2013/08/09) includeしたファイルのキャッシュをクリア 411 JspIncludeReader.cacheClear(); 412 } 413 catch( final TransformerConfigurationException ex ) { 414 final String errMsg = xslFile + "ファイルの XSLT 解析に失敗しました。" + CR 415 // + ex.getMessageAndLocation() // 6.4.0.2 (2015/12/11) 行番号がうまく取り出せない。 416 + errListener.toString(); // 6.4.0.2 (2015/12/11) エラー内容が重複するかも。 417 throw new OgRuntimeException( errMsg,ex ); 418 } 419 finally { 420 Closer.ioClose( xslReader ); 421 xslReader = null; 422 } 423 } 424 425 /** 426 * 実行中の入力ファイル名などの属性情報を パラメータとして設定するかどうかを指定します。 427 * 428 * このパーサーでは、内部で実行中の入力ファイル情報を パラメータとして設定できます。 429 * useFileInfo( true ) とセットすると、以下の4項目が内部的にセットされます。 430 * 431 * 入力ファイル(inXMLのフルパス) : FILEPATH (例: G:\webapps\gf\jsp\DOC10\query.jsp) 432 * 入力親フォルダ(inXMLの親フォルダ) : ADDRESS (例: DOC10) 433 * 入力ファイル(inXMLのファイル名) : FILENAME (例: query.jsp) 434 * 入力ファイル(inXMLの更新日付 ) : MODIFIED (例: yyyyMMddHHmmss形式) 435 * 436 * @og.rev 4.0.0.0 (2007/09/25) ParameterMetaData を使用したパラメータ設定追加。 437 * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正します。 438 * 439 * xsl ファイルでは、xsl:param で宣言し、xsl:value-of で取り出します。 440 * <xsl:param name="ADDRESS" select="" /> と宣言しておき、必要な箇所で 441 * <xsl:value-of select="$ADDRESS" /> とすれば、取得できます。 442 * 443 * 初期値は、false(セットしない) です。 444 * 445 * @param flag セットする:true/セットしない:false 446 */ 447 public void useFileInfo( final boolean flag ) { 448 isFileInfo = flag; 449 } 450 451 /** 452 * ファイル名指定で XML,XSL,OUTファイルを指定する場合のエンコードを指定します。 453 * 454 * 初期値は、UTF-8 です。 455 * 456 * @param encode エンコード 457 */ 458 public void useEncode( final String encode ) { 459 this.encode = encode; 460 } 461 462 /** 463 * 実行中の入力ファイル名などの属性情報を パラメータとして取得します。 464 * 465 * 入力ファイル(inXMLのフルパス) : FILEPATH (例: G:\webapps\gf\jsp\DOC10\query.jsp) 466 * 入力ファイル(inXMLのファイル名) : FILENAME (例: query.jsp) 467 * 入力親フォルダ(inXMLの親フォルダ) : ADDRESS (例: DOC10) 468 * 入力ファイル(inXMLの更新日付 ) : MODIFIED (例: yyyyMMddHHmmss形式) 469 * 470 * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正します。 471 * 472 * @param xmlIn XML入力ファイル 473 * 474 * @return HybsEntry配列 475 */ 476 private HybsEntry[] getXmlParameter( final String xmlIn ) { 477 HybsEntry[] entry = new HybsEntry[4] ; 478 479 entry[0] = new HybsEntry( "FILEPATH" , xmlIn) ; 480 481 final File xmlFile = new File( xmlIn ); 482 entry[1] = new HybsEntry( "FILENAME" , xmlFile.getName()) ; 483 484 final File parentFile = xmlFile.getParentFile() ; 485 // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid if (x != y) ..; else ..; 486 entry[2] = parentFile == null 487 ? new HybsEntry( "ADDRESS" , "" ) 488 : new HybsEntry( "ADDRESS" , parentFile.getName()) ; 489 490 final String lastDate = DateSet.getDate( xmlFile.lastModified() , "yyyyMMddHHmmss" ) ; // 5.5.7.2 (2012/10/09) HybsDateUtil を利用 491 entry[3] = new HybsEntry( "MODIFIED" , lastDate ) ; 492 493 return entry ; 494 } 495 496 /** 497 * Transformer オブジェクト に、パラメータを設定します。 498 * 499 * 指定されたパラメーターキーは、xsl ファイルでは、xsl:param で宣言し、 500 * xsl:value-of で取り出します。 501 * <xsl:param name="ADDRESS" select="" /> と宣言しておき、必要な箇所で 502 * <xsl:value-of select="$ADDRESS" /> とすれば、取得できます。 503 * 504 * @param former Transformerオブジェクト 505 * @param entry パラメータ配列(可変長引数) 506 */ 507 private void parameterSet( final Transformer former,final HybsEntry... entry ) { 508 if( entry != null && entry.length > 0 ) { // 6.1.1.0 (2015/01/17) 可変長引数でもnullは来る。 509 final int size = entry.length; 510 for( int i=0; i<size; i++ ) { 511 final String key = entry[i].getKey() ; 512 final String val = entry[i].getValue(); 513 former.setParameter( key , val ); 514 } 515 } 516 } 517 518 /** 519 * このオブジェクトの内部文字列表現を返します。 520 * 521 * 接続URL + "," + 接続ユーザー + " (" + 作成日付 + ")" です。 522 * 523 * @return 内部文字列表現 524 * @og.rtnNotNull 525 */ 526 @Override 527 public String toString() { 528 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ) 529 .append( "XSL File:" ).append( xslFile ).append( CR ) 530 .append( "XML File:" ).append( xmlFile ).append( CR ) 531 .append( "OUT File:" ).append( outFile ).append( CR ); 532 533 return buf.toString() ; 534 } 535 536 /** 537 * エラー情報の内部XML文字列表現を返します。 538 * 539 * エラー時の情報も、XML化して保存する為の簡易処理。 540 * ここでは、XMLスキーマは、固定で、GF70 の形式になります。 541 * 542 * @og.rev 4.2.3.0 (2008/05/26) エラー発生時のXMLファイルを追加します。 543 * @og.rev 5.2.1.0 (2010/10/01) XML形式を変更します。(TEXT⇒TEXT_DATA) 544 * 545 * @param entry HybsEntry配列 546 * @param ex エラー情報 547 * 548 * @return XMLの部分文字列 549 * @og.rtnNotNull 550 */ 551 private String toXmlRow( final HybsEntry[] entry,final TransformerException ex ) { 552 final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE ); 553 554 // 6.0.2.5 (2014/10/31) char を append する。 555 buf.append( "<ROW>" ).append( CR ); 556 if( paramEntry != null ) { 557 for( int i=0; i<paramEntry.length; i++ ) { 558 final String key = paramEntry[i].getKey() ; 559 final String val = paramEntry[i].getValue(); 560 buf.append( " <" ).append( key ).append( '>' ) 561 .append( val ) 562 .append( "</" ).append( key ).append( '>' ) 563 .append( CR ); 564 } 565 } 566 567 if( entry != null ) { 568 for( int i=0; i<entry.length; i++ ) { 569 final String key = entry[i].getKey() ; 570 final String val = entry[i].getValue(); 571 buf.append( " <" ).append( key ).append( '>' ) 572 .append( val ) 573 .append( "</" ).append( key ).append( '>' ) 574 .append( CR ); 575 } 576 } 577 578 buf.append( " <TAGNAME />" ).append( CR ) // XML なので、このまま。 579 .append( " <MSGCD>XML_ERROR</MSGCD>" ).append( CR ) 580 .append( " <MSGTXT>XML-XSLT 変換に失敗しました。</MSGTXT>" ).append( CR ); 581 582 String errMsg = StringUtil.htmlFilter( ex.getMessage() ); 583 final int indx = errMsg.lastIndexOf( "Exception:" ); 584 if( indx >= 0 ) { 585 errMsg = errMsg.substring( indx + "Exception:".length() ); 586 } 587 buf.append( " <TEXT_DATA>" ).append( errMsg ).append( CR ) // 5.2.1.0 (2010/10/01) 588 .append( " Location:" ).append( ex.getLocationAsString() ).append( CR ) 589 .append( "</TEXT_DATA>" ).append( CR ) // 5.2.1.0 (2010/10/01) 590 .append( "</ROW>" ).append( CR ); 591 592 return buf.toString() ; 593 594/* 595 <ROW> 596 <SYSTEM_ID> </SYSTEM_ID> 597 <ADDRESS > </ADDRESS> 598 <FILENAME > </FILENAME> 599 <FILEPATH > </FILEPATH> 600 <MODIFIED > </MODIFIED> 601 <TAGNAME > </TAGNAME> 602 <MSGCD > </MSGCD> 603 <MSGTXT > </MSGTXT> 604 <TEXT_DATA> </TEXT_DATA> 605 </ROW> 606*/ 607 } 608 609 /** 610 * テスト用のメインメソッド。 611 * 612 * java org.opengion.fukurou.xml.XSLT in_xml in_xsl out_xml 613 * 614 * @param args コマンド引数配列 615 * @throws IOException 入出力エラーが発生した場合 616 */ 617 public static void main( final String[] args ) throws IOException { 618 if( args.length != 3 ) { 619 LogWriter.log( "Usage: java org.opengion.fukurou.xml.XSLT in_xml in_xsl out_xml" ); 620 LogWriter.log( " XML 入力ファイルに、XSL 入力ファイルを適用して、" ); 621 LogWriter.log( " XSLT変換を行います。" ); 622 LogWriter.log( " 結果は、XML ファイルにセーブします。" ); 623 LogWriter.log( " out_xml に System.out を指定すると標準出力に出力します。" ); 624 return ; 625 } 626 627 final XSLT xslt = new XSLT(); 628 xslt.setXslFile( args[1] ); 629 xslt.setOutFile( args[2],false ); 630 xslt.transform( args[0] ); 631 xslt.close(); 632 } 633}