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     */
016    package org.opengion.fukurou.xml;
017    
018    import org.opengion.fukurou.util.Closer ;
019    import org.opengion.fukurou.util.HybsEntry ;
020    import org.opengion.fukurou.util.FileUtil ;
021    import org.opengion.fukurou.util.StringUtil ;
022    import org.opengion.fukurou.util.LogWriter;
023    import org.opengion.fukurou.util.HybsDateUtil ;
024    
025    import java.io.Reader;
026    import java.io.Writer;
027    import java.io.File;
028    import java.io.IOException;
029    import java.io.StringReader;
030    // import java.text.DateFormat;
031    // import java.text.SimpleDateFormat;
032    // import java.util.Date;
033    // import java.util.Locale;
034    
035    import javax.xml.transform.TransformerException;
036    import javax.xml.transform.TransformerConfigurationException;
037    import javax.xml.transform.TransformerFactory;
038    import javax.xml.transform.Transformer;
039    import javax.xml.transform.stream.StreamSource;
040    import javax.xml.transform.stream.StreamResult;
041    
042    /**
043     * XML 入力ファイルに、XSL 入力ファイルを適用して?XSLT変換を行います?
044     * 結果は、XML 出力ファイルにセーブします?
045     * ?ァイルの代わりに、Writer,Reader を設定することも可能です?
046     *
047     * こ?パ?サーでは、?部で実行中の入力ファイル???パラメータとして設定できます?
048     * useFileInfo( true ) とセ?すると、以下???目が?部?セ?されます?
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" ;   // 入力X??ファイル
062     *      String outFile = "outXMLfile.xml" ;  // 出力X??ファイル
063     *      String inXML   = "inXMLfile.xml" ;   // 入力X??ファイル
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     */
075    public class XSLT {
076            private static final String CR = System.getProperty("line.separator") ;
077            /** 初期 ENCODE ?{@value}       */
078            public static final String ENCODE = "UTF-8" ;
079    
080            private Transformer transformer = null;
081    
082            private String          encode          = ENCODE;
083            private String          xmlFile         = null;
084            private String          xslFile         = null;
085            private String          outFile         = null;
086            private Reader          xslReader       = null;
087            private Writer          outWriter       = null;
088            private HybsEntry[] paramEntry  = null;
089            private boolean         isFileInfo      = false;
090            private boolean         isErrClose      = true;
091            private boolean         isErrXmlIn      = false;        // useErrXmlIn ?isErrXmlIn 変更
092            private boolean         isInclude       = true;         // 4.2.3.0 (2008/05/26)
093            private StreamResult result = null;
094    
095    //      private DateFormat      formatter       = null;                 // HybsDateUtil を利用
096    
097            private String          jspIncludeData  = null;
098    
099            /**
100             * 入力XSLファイルを??します?
101             *
102             * @param       file    入力XSLファイル
103             * @see #setXslFile( Reader )
104             */
105            public void setXslFile( final String file ) {
106                    xslFile = file;
107                    setXslFile( FileUtil.getBufferedReader( new File( xslFile ),encode ) );
108            }
109    
110            /**
111             * 入力XSLリー??を??します?
112             *
113             * @param       reader  入力XSLリー??
114             * @see #setXslFile( String )
115             */
116            public void setXslFile( final Reader reader ) {
117                    transformer = null;
118                    xslReader = reader;
119            }
120    
121            /**
122             * 結果XML ファイル名と、そのオープン方法を?します?
123             * 結果XML ファイルを?追記す?append=true)か新規作?する(append=false)か指定します?
124             * なお?結果XML ファイル(outFile) を指定しな?=null)か?特別な名称 "System.out"
125             * ??を渡すと、標準?力に 結果を?力します?
126             *
127             * @param       file    出力ファイル?null また??System.out" ??時?、標準??
128             * @param append [true]追記す?false:新規作?する]
129             */
130            public void setOutFile( final String file,final boolean append ) {
131                    outFile = file ;
132                    setOutFile( FileUtil.getPrintWriter( new File( outFile ),encode,append ) );
133            }
134    
135            /**
136             * 結果XML ??タを?力する?Writer を指定します?
137             * ファイル、標準?力?JSPWriter など、?に応じて Writer を作?してください?
138             * 標準??System.out)の場合?、NonClosePrintWriter クラスなどの非close()処?を?
139             * JSPWriterの場合?、NonFlushPrintWriter クラスなどの非flush()、close()処?を?
140             * 使用してください?
141             *
142             * @param       writer  出力するWriter
143             */
144            public void setOutFile( final Writer writer ) {
145                    Closer.ioClose( outWriter );
146                    outWriter = writer ;
147                    result = new StreamResult( outWriter );
148            }
149    
150            /**
151             * 結果XML ライターに、指定???タを書き?します?
152             *
153             * @param       outData 書き?すデータ
154             */
155            public void setOutData( final String outData ) {
156                    if( outData != null && outData.length() > 0 ) {
157                            try {
158                                    outWriter.write( outData );
159                                    outWriter.write( CR );
160                            }
161                            catch( IOException ex ) {
162                                    String errMsg = "ライターに??タ登録を失敗しました? + CR
163                                                                    + ex.getMessage() ;
164                                    close();
165                                    throw new RuntimeException( errMsg,ex );
166                            }
167                    }
168            }
169    
170            /**
171             * XML ファイルをXSLT変換します?
172             * XML 入力ファイルに、XSL 入力ファイルを適用して?XSLT変換を行います?
173             * 結果は、XML ファイルにセーブします?
174             * 拡張子が?jsp』?場合?jsp:directive.include 処?行います?
175             *
176             * @og.rev 4.0.0.2 (2007/12/10) 拡張子が?jsp』?場合?jsp:directive.include 処?行います?
177             *
178             * @param       file    入力XMLファイル
179             * @see #transform( Reader )
180             */
181            public void transform( final String file ) {
182                    transform( file, isInclude );
183            }
184    
185            /**
186             * XML ファイルをXSLT変換します?
187             * XML 入力ファイルに、XSL 入力ファイルを適用して?XSLT変換を行います?
188             * 結果は、XML ファイルにセーブします?
189             * 引数の isJspInclude によって、jsp:directive.include 処?行うかど?判断します?
190             *
191             * @og.rev 4.2.3.0 (2008/05/26) jsp:directive.include 処??実施可否を引数?します?
192             * @og.rev 5.2.1.0 (2010/10/01) JspIncludeReader#getString の第?引数を?
193             *
194             * @param       file    入力XMLファイル
195             * @param       isJspInclude    jsp:directive.include 処?行うかど??
196             * @see #transform( Reader )
197             */
198            public void transform( final String file, final boolean isJspInclude ) {
199                    xmlFile = file;
200    
201                    if( xmlFile.endsWith( ".jsp" ) && isJspInclude ) {
202    //              if( xmlFile.endsWith( ".jsp" ) ) {
203    //                      transform( new JspIncludeReader().getReader( new File( xmlFile ),encode ) );
204    //                      jspIncludeData = new JspIncludeReader().getString( new File( xmlFile ),encode,false );
205                            jspIncludeData = new JspIncludeReader().getString( new File( xmlFile ),encode );                // 5.2.1.0 (2010/10/01)
206                            transform( new StringReader( jspIncludeData ) );
207                    }
208                    else {
209                            transform( FileUtil.getBufferedReader( new File( xmlFile ),encode ) );
210                    }
211            }
212    
213            /**
214             * XML ファイルをXSLT変換します?
215             * XML 入力リー??に、XSL 入力リー??を適用して?XSLT変換を行います?
216             * 結果は、XML ライターに書き?します?
217             * こ?処??終?に、?力XML リー?? は、close() されます?
218             *
219             * @og.rev 5.6.5.2 (2013/06/21) エラーメ?ージが判りにくいので、追記します?
220             *
221             * @param       xmlReader       入力XML リー??
222             * @see #transform( String )
223             */
224            public void transform( final Reader xmlReader ) {
225                    HybsEntry[] entry = null;
226    
227                    try {
228                            if( transformer == null ) {
229                                    init();
230                            }
231                            else {
232                                    transformer.reset();
233                            }
234    
235                            // 入力XMLファイルのファイル??を設定します?
236                            if( isFileInfo && xmlFile != null ) {
237                                    entry = getXmlParameter( xmlFile );
238                                    parameterSet( transformer,entry );
239                            }
240                            xmlFile = null ;
241    
242                            // 入力XMLリー??からStreamSourceを作る
243                            StreamSource data = new StreamSource( xmlReader );
244    
245                            transformer.transform( data,result );
246                    }
247                    catch( TransformerException ex ) {
248                            String errMsg = "XML-XSLT 変換に失敗しました? + CR
249                                                                    + ex.getMessage() ;
250    
251                            // 5.6.5.2 (2013/06/21) エラーメ?ージが判りにくいので、追記します?
252                            if( errMsg.indexOf( "プロローグにはコン???できません" ) >= 0 ) {
253                                    errMsg = errMsg + CR + "(UTF-8変換時に、BOMが付くとこ?エラーが?ます?BOMを外してみてください?" ;
254                            }
255    
256                            if( isErrXmlIn ) { setOutData( toXmlRow( entry, ex ) ); }
257    
258                            if( isErrClose ) { close(); }
259                            throw new RuntimeException( errMsg,ex );
260                    }
261                    finally {
262                            Closer.ioClose( xmlReader );
263                    }
264            }
265    
266            /**
267             * Transformer オブジェクトに対して、Parameter を設定します?
268             *
269             * ?されたパラメーターキーは、xsl ファイルでは、xsl:param で宣??
270             * xsl:value-of で取り出します?
271             * <xsl:param name="ADDRESS" select="" /> と宣?ておき、?な?で
272             * <xsl:value-of select="$ADDRESS"     /> とすれば、取得できます?
273             *
274             * @param       entry   HybsEntry配?
275             */
276            public void setParamEntry( final HybsEntry[] entry ) {
277                    if( entry != null && entry.length > 0 ) {
278                            paramEntry = new HybsEntry[entry.length];
279                            System.arraycopy( entry,0,paramEntry,0,entry.length );
280                    }
281            }
282    
283            /**
284             * transform 処?にエラーが発生した?合に、?力ファイルを閉じるかど?を指定します?
285             *
286             * 処??中でエラーが発生した?合に、そこで処?中断するか?それとも?
287             * 無視して、さらに処?進めるかを?することが可能です?
288             * 継続して処?進めた??合?、?力ファイルを閉じな?め?false ?
289             * 設定します?ただし?エラー時には、RuntimeException は throw されます?
290             * 初期値は、true(閉じ?です?
291             *
292             * @param       flag    エラー時クローズ [true:閉じ?false:閉じない]
293             */
294            public void errClose( final boolean flag ) {
295                    isErrClose = flag ;
296            }
297    
298            /**
299             * transform 処?エラーを?出力ファイルに、XML形式でエラーを追記するかど?を指定します?
300             *
301             * 処??中でエラーが発生した?合に、ログ?ではなく?結果XMLファイルに?
302             * エラー???エラーファイルなどを埋め込?、XMLファイルとしてDB登録??
303             * そ?他集計等に使えます?
304             * 今?、GE70 スキーマ形式?ファイルしか作?できません?
305             * これは?errClose( boolean ) メソ?と共に使用すると効果的です?
306             * つまり?errClose = false; にして、エラー時でも?力ファイルを閉じずに?
307             * 処?続ける事で、エラーメ?ージもXMLファイルとして?できます?
308             * 初期値は、false(使用しな?です?
309             *
310             * @param       flag    エラー時XML形?[false:使用しな?true:使用する]
311             */
312            public void useErrXmlIn( final boolean flag ) {
313                    isErrXmlIn = flag ;
314            }
315    
316            /**
317             * jsp:directive.include 発見時に、そのファイル?INCLUDE するかを?するかど?を指定しま?初期値:true:使用する)
318             *
319             * 引数の処?象ファイル(transformの引数ファイル)が??jsp』?場合?
320             * jsp:directive.include 発見時に、そのファイル?INCLUDE するかを?するか
321             * ど?を指定します?
322             * インクルードされたファイルとあわせて、正規?XML にならな?、パーサー
323             * エラーが発生します?
324             * JSPソース解析を行うには、INCLUDE ファイルも?慮しな?正確な結果?
325             * 得られませんが?INCLUDE 先?ファイルまで合わせる?があるため?
326             * 場合によっては、INCLUDEファイルを無視しなければならな?ースがあります?
327             * 初期値は、true(使用する)です?
328             *
329             * @param       flag    エラー時XML形?[false:使用しな?true:使用する]
330             */
331            public void jspInclude( final boolean flag ) {
332                    isInclude = flag ;
333            }
334    
335            /**
336             * 入力XSLファイルのストリー?閉じます?
337             *
338             */
339            public void close() {
340                    Closer.ioClose( outWriter );
341            }
342    
343            /**
344             * XML ファイルをXSLT変換します?
345             * XML 入力ファイルに、XSL 入力ファイルを適用して?XSLT変換を行います?
346             * 結果は、XML ファイルにセーブします?
347             * なお?結果XML ファイル(outFile) に、特別な名称 "System.out" ??を渡すと?
348             * 標準?力に 結果を?力します?
349             */
350            private void init() {
351                    try {
352                            // xsl属?からStreamSourceを作る
353                            StreamSource style = new StreamSource( xslReader );
354    
355                            // Transformerを作り、XMLを変換する
356                            TransformerFactory tFactory = TransformerFactory.newInstance();
357                            transformer = tFactory.newTransformer( style );
358    
359                            parameterSet( transformer,paramEntry );
360                    }
361                    catch( TransformerConfigurationException ex ) {
362                            String errMsg = xslFile + "ファイルの XSLT 解析に失敗しました? + CR
363                                                                    + ex.getMessage() ;
364                            throw new RuntimeException( errMsg,ex );
365                    }
366                    finally {
367                            Closer.ioClose( xslReader );
368                            xslReader = null;
369                    }
370            }
371    
372            /**
373             * 実行中の入力ファイル名などの属????パラメータとして設定するかど?を指定します?
374             *
375             * こ?パ?サーでは、?部で実行中の入力ファイル???パラメータとして設定できます?
376             * useFileInfo( true ) とセ?すると、以下???目が?部?セ?されます?
377             *
378             * 入力ファイル(inXMLのフルパス)     : FILEPATH  (? G:\webapps\gf\jsp\DOC10\query.jsp)
379             * 入力親フォル?inXMLの親フォル? : ADDRESS   (? DOC10)
380             * 入力ファイル(inXMLのファイル?   : FILENAME  (? query.jsp)
381             * 入力ファイル(inXMLの更新日? )   : MODIFIED  (? yyyyMMddHHmmss形?
382             *
383             * @og.rev 4.0.0.0 (2007/09/25) ParameterMetaData を使用したパラメータ設定追??
384             * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正します?
385             *
386             * xsl ファイルでは、xsl:param で宣?、xsl:value-of で取り出します?
387             * &lt;xsl:param name="ADDRESS" select="" /&gt; と宣?ておき、?な?で
388             * &lt;xsl:value-of select="$ADDRESS"     /&gt; とすれば、取得できます?
389             *
390             * 初期値は、false(セ?しな? です?
391             *
392             * @param       flag    セ?する:true/セ?しな?false
393             */
394            public void useFileInfo( final boolean flag ) {
395                    isFileInfo = flag;
396    //              if( isFileInfo ) {
397    //                      formatter = new SimpleDateFormat( "yyyyMMddHHmmss",Locale.JAPAN );
398    //              }
399            }
400    
401            /**
402             * ファイル名指定で XML,XSL,OUTファイルを指定する?合?エンコードを?します?
403             *
404             * 初期値は、UTF-8 です?
405             *
406             * @param       encode  エンコー?
407             */
408            public void useEncode( final String encode ) {
409                    this.encode = encode;
410            }
411    
412            /**
413             * 実行中の入力ファイル名などの属????パラメータとして取得します?
414             *
415             * 入力ファイル(inXMLのフルパス)     : FILEPATH  (? G:\webapps\gf\jsp\DOC10\query.jsp)
416             * 入力ファイル(inXMLのファイル?   : FILENAME  (? query.jsp)
417             * 入力親フォル?inXMLの親フォル? : ADDRESS   (? DOC10)
418             * 入力ファイル(inXMLの更新日? )   : MODIFIED  (? yyyyMMddHHmmss形?
419             *
420             * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正します?
421             *
422             * @param       xmlIn   XML入力ファイル
423             *
424             * @return      HybsEntry配?
425             */
426            private HybsEntry[] getXmlParameter( final String xmlIn ) {
427                    HybsEntry[] entry = new HybsEntry[4] ;
428    
429                    entry[0] = new HybsEntry( "FILEPATH" , xmlIn) ;
430    
431                    File xmlFile = new File( xmlIn );
432                    entry[1] = new HybsEntry( "FILENAME" , xmlFile.getName()) ;
433    
434                    File parentFile = xmlFile.getParentFile() ;
435                    if( parentFile != null ) {
436                            entry[2] = new HybsEntry( "ADDRESS"  , parentFile.getName()) ;
437                    }
438                    else {
439                            entry[2] = new HybsEntry( "ADDRESS"  , "" ) ;
440                    }
441    
442    //              String lastDate = formatter.format( new Date( xmlFile.lastModified() ) ) ;
443                    String lastDate = HybsDateUtil.getDate( xmlFile.lastModified() , "yyyyMMddHHmmss" ) ;           // 5.5.7.2 (2012/10/09) HybsDateUtil を利用
444                    entry[3] = new HybsEntry( "MODIFIED" , lastDate ) ;
445    
446                    return entry ;
447            }
448    
449            /**
450             * Transformer オブジェク?に、パラメータを設定します?
451             *
452             * ?されたパラメーターキーは、xsl ファイルでは、xsl:param で宣??
453             * xsl:value-of で取り出します?
454             * <xsl:param name="ADDRESS" select="" /> と宣?ておき、?な?で
455             * <xsl:value-of select="$ADDRESS"     /> とすれば、取得できます?
456             *
457             * @param former Transformerオブジェク?
458             * @param entry  パラメータ配?
459             */
460            private void parameterSet( final Transformer former,final HybsEntry[] entry ) {
461                    if( entry != null ) {
462                            int size   = entry.length;
463                            for( int i=0; i<size; i++ ) {
464                                    String key = entry[i].getKey() ;
465                                    String val = entry[i].getValue();
466                                    former.setParameter( key , val );
467                            }
468                    }
469            }
470    
471            /**
472             * こ?オブジェクト????表現を返します?
473             *
474             * 接続URL + "," + 接続ユーザー + " (" + 作?日?+ ")" です?
475             *
476             * @return ???表現
477             */
478            @Override
479            public String toString() {
480                    StringBuilder buf = new StringBuilder();
481    
482                    buf.append( "XSL File:" ).append( xslFile ).append( CR );
483                    buf.append( "XML File:" ).append( xmlFile ).append( CR );
484                    buf.append( "OUT File:" ).append( outFile ).append( CR );
485    
486                    return buf.toString() ;
487            }
488    
489            /**
490             * エラー??の?XML??表現を返します?
491             *
492             * エラー時???も?XML化して保存する為の簡易???
493             * ここでは、XMLスキーマ?、固定で、GF70 の形式になります?
494             *
495             * @og.rev 4.2.3.0 (2008/05/26) エラー発生時のXMLファイルを追?ます?
496             * @og.rev 5.2.1.0 (2010/10/01) XML形式を変更します?(TEXT⇒TEXT_DATA)
497             *
498             * @param       entry   HybsEntry配?
499             * @param       ex              エラー??
500             *
501             * @return XMLの部?字?
502             */
503            private String toXmlRow( final HybsEntry[] entry,final TransformerException ex ) {
504                    StringBuilder buf = new StringBuilder();
505    
506                    buf.append( "<ROW>" ).append( CR );
507                    if( paramEntry != null ) {
508                            for( int i=0; i<paramEntry.length; i++ ) {
509                                    String key = paramEntry[i].getKey() ;
510                                    String val = paramEntry[i].getValue();
511                                    buf.append( "  <" ).append( key ).append( ">" );
512                                    buf.append( val );
513                                    buf.append( "</" ).append( key ).append( ">" );
514                                    buf.append( CR );
515                            }
516                    }
517    
518                    if( entry != null ) {
519                            for( int i=0; i<entry.length; i++ ) {
520                                    String key = entry[i].getKey() ;
521                                    String val = entry[i].getValue();
522                                    buf.append( "  <" ).append( key ).append( ">" );
523                                    buf.append( val );
524                                    buf.append( "</" ).append( key ).append( ">" );
525                                    buf.append( CR );
526                            }
527                    }
528    
529                    buf.append( "  <TAGNAME />" ).append( CR );
530                    buf.append( "  <MSGCD>XML_ERROR</MSGCD>" ).append( CR );
531                    buf.append( "  <MSGTXT>XML-XSLT 変換に失敗しました?/MSGTXT>" ).append( CR );
532    
533                    String errMsg = StringUtil.htmlFilter( ex.getMessage() );
534                    int indx = errMsg.lastIndexOf( "Exception:" );
535                    if( indx >= 0 ) {
536                            errMsg = errMsg.substring( indx + "Exception:".length() );
537                    }
538                    buf.append( "  <TEXT_DATA>" ).append( errMsg ).append( CR );              // 5.2.1.0 (2010/10/01)
539                    buf.append( " Location:" ).append( ex.getLocationAsString() ).append( CR );
540    
541                    // 4.2.3.0 (2008/05/26)
542            //      if( jspIncludeData != null ) {
543            //              buf.append( StringUtil.htmlFilter( jspIncludeData ) );
544            //      }
545    
546                    buf.append( "</TEXT_DATA>" ).append( CR );                // 5.2.1.0 (2010/10/01)
547                    buf.append( "</ROW>" ).append( CR );
548    
549                    return buf.toString() ;
550    
551    /*
552               <ROW>
553                     <SYSTEM_ID>  </SYSTEM_ID>
554                     <ADDRESS  >  </ADDRESS>
555                     <FILENAME >  </FILENAME>
556                     <FILEPATH >  </FILEPATH>
557                     <MODIFIED >  </MODIFIED>
558                     <TAGNAME  >  </TAGNAME>
559                     <MSGCD    >  </MSGCD>
560                     <MSGTXT   >  </MSGTXT>
561                     <TEXT_DATA>  </TEXT_DATA>
562               </ROW>
563    */
564            }
565    
566            /**
567             * ?ト用のメインメソ?
568             *
569             * java XSLT in_xml in_xsl out_xml
570             *
571             * @param       args    コマンド引数配?
572             */
573            public static void main( final String[] args ) throws IOException {
574                    if( args.length != 3 ) {
575                            LogWriter.log( "Usage: java XSLT in_xml in_xsl out_xml" );
576                            LogWriter.log( "  XML 入力ファイルに、XSL 入力ファイルを適用して? );
577                            LogWriter.log( "  XSLT変換を行います?" );
578                            LogWriter.log( "  結果は、XML ファイルにセーブします?" );
579                            LogWriter.log( "  out_xml に System.out を指定すると標準?力に出力します?" );
580                            return ;
581                    }
582    
583                    XSLT xslt = new XSLT();
584                    xslt.setXslFile( args[1] );
585                    xslt.setOutFile( args[2],false );
586                    xslt.transform( args[0] );
587                    xslt.close();
588            }
589    }