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

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

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

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

2回答

2004閲覧

Javascriptを使用して、xmlファイルの自動翻訳(テキスト置き換え)プログラムを作成したいです。

l_kotomai

総合スコア12

XML

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2019/04/29 08:36

編集2019/04/30 06:55

前提・実現したいこと

#1. Javascriptを使用して、xmlファイルの自動翻訳(テキスト置き換え)プログラムを作成したいです。
プログラミングは初心者です

  • Windows上からbatファイルによりJavascriptを呼び出し、あるxmlファイルに書かれている特定のタグで囲まれた英文を、データベースから一致する英文と日本語の組み合わせを探し出し、体裁を崩さぬように新しいxmlファイルに書き出したい。
  • また、英文には特殊文字列が使用されている場合があります。
  • 英文は複数行に改行されています
  1. FileEnglish.xmlから、<description>文字列</description>で囲まれた部分を一行ずつ読み込む
  2. FileJapanese.xmlからFileEnglish.xmlで読み込んだ文字列を探す
  3. 一致する文字列が見つかった場合、対応する英文ペアとなっている日本語 <Japanese> ~ </Japanese>の組み合わせを取得する。
  4. FileOutput.xmlに日本語化したFileEnglish.xmlの内容を書き出す。

#2. 使用するファイルは次の通りです

    1. FileEnglish.xml -- 翻訳対象のファイル。文字コード[ UCS-2 LE BOM ]でエンコードされています。文字化けしているように見えますがこれで普通です。
  • <description>のタグで囲まれた複数行を取得して日本語化します。

xml

1 <Title>TESTFILE</Title> 2 <installStep name="Main"> 3 <optionalFileGroups order="Explicit"> 4 <description>These are English sentences 01&#13;&#10; 5&#13;&#10; 6These are English sentences 02.&#13;&#10; 7&#13;&#10; 8- These are English sentences 04+&#13;&#10; 9&#13;&#10; 10</description> 11 <typeDescriptor> 12 </typeDescriptor> 13 <description>These are English sentences 06.&#13;&#10; 14&#13;&#10; 15These are speculary large and long English sentences 07.These are speculary large and long English sentences 07&#13;&#10; 16&#13;&#10; 17- These are English sentences 08(comment)</description> 18 <typeDescriptor> 19 </typeDescriptor> 20 <description>These are English sentences 09&#13;&#10; 21&#13;&#10; 22- These are English sentences 10:&#13;&#10; 23- sentences 11&#13;&#10; 24- words 12&#13;&#10; 25</description>
    1. FileJapanese.xml -- 英文と日本語訳が対になって格納されているファイル
  • <block番号>のタグでグループ化され、それぞれに<description>の内容と訳文に当たる<Japanese>があります。

xml

1<Block0001> 2<description>These are English sentences 01&#13;&#10; 3&#13;&#10; 4These are English sentences 02.&#13;&#10; 5&#13;&#10; 6- These are English sentences 04+&#13;&#10; 7&#13;&#10; 8</description> 9<Japanese>日本語文章 01&#13;&#10; 10&#13;&#10; 11日本語文章 02.&#13;&#10; 12&#13;&#10; 13- 日本語文章 04+&#13;&#10; 14&#13;&#10; 15</Japanese> 16</Block0001><Block0002> 17<description>These are English sentences 06.&#13;&#10; 18&#13;&#10; 19These are speculary large and long English sentences 07.These are speculary large and long English sentences 07&#13;&#10; 20&#13;&#10; 21- These are English sentences 08(comment)</description> 22<Japanese>日本語文章 06.&#13;&#10; 23&#13;&#10; 24日本語文章 07&#13;&#10; 25&#13;&#10; 26- 日本語文章 08(comment)</Japanese> 27</Block0002><Block0003> 28<description>These are English sentences 09&#13;&#10; 29&#13;&#10; 30- These are English sentences 10:&#13;&#10; 31- sentences 11&#13;&#10; 32- words 12&#13;&#10; 33</description> 34<Japanese>日本語文章 09&#13;&#10; 35&#13;&#10; 36- 日本語文章 10:&#13;&#10; 37- 日本語文章 11&#13;&#10; 38- 日本語文章 12&#13;&#10; 39</Japanese> 40</Block0003> 41
    1. FileOutput.xml -- 翻訳後(出力後)のとして期待するファイルは、「FileEnglish.xml」の<description>~</description>で囲まれた行を日本語と置き換えたものです
    1. Test.js -- 翻訳プログラムのテスト版

発生している問題・エラーメッセージ

  • 111行目(arrayEN.forEach(function(value){)でエラー「オブジェクトでサポートされていないプロパティまたはメソッドです」が表示されて中断する
  • 途中経過のファイルでは、翻訳前のと同じ内容のファイルが出力されるだけで、うまくいってませんでした

js

1// ここから「Test03.js」(このファイル自体は「Shift_JIS」で保存すること) 2// ファイル名指定 3var FileConfig = "FileJapanese.xml"; 4var FileEng = "FileEnglish.xml"; 5var FileOutput = "FileOutput.xml"; 6 7//翻訳対象タグの指定 8//var regStrEN = /(<StringEN>)([^<]*)(</StringEN>)/; 9var regDescEn1 = /([^<]*)(<description>)([^<]*)/; 10var regDescEn2 = /([^<]*)(</description>)([^<]*)/; 11// FileENの<desc~>の終わりと始まり 12var regStrENJA1 = /([^<]*)(<Japanese>)([^<]*)/; 13var regStrENJA2 = /([^<]*)(</Japanese>)([^<]*)/; 14// FileJAの訳文タグ<Japanese>の終わりと始まり 15 16//<description>の格納、比較用の配列を宣言 17var arrayEN = new Array(); 18var arrayJA = new Array(); 19var arrayENJA = new Array(); 20 21var adTypeText = 2; // テキストモード 22var adReadLine = -2; // 一行毎に読み込み 23var adReadLineJA = -2; //FileJAの読み込み行 24var adWriteLine = 1; // Writeモード (改行する) 25 26var adSaveCreateNotExist = 1; // ない場合は新規作成 27var adSaveCreateOverWrite = 2; // ある場合は上書き 28var objStreamJA; 29var objStreamEN; 30var objStreamOUT; 31 32var strTextJA; 33var strTextEN; 34var strTextENJA; 35 36var decTotal = 0; // 置換件数 37 38// FileJapanese.xml をテキストモード(UTF-8) で読み込みファイルとして開く 39objStreamJA = new ActiveXObject( "ADODB.Stream" ); 40objStreamJA.Type = adTypeText; 41objStreamJA.charset = "utf-8"; 42objStreamJA.Open(); 43objStreamJA.LoadFromFile( FileConfig ); 44 45// FileEnglish.xml をテキストモード(UTF-8) で読み込みファイルとして開く 46objStreamEN = new ActiveXObject( "ADODB.Stream" ); 47objStreamEN.Type = adTypeText; 48objStreamEN.charset = "utf-8"; 49objStreamEN.Open(); 50objStreamEN.LoadFromFile( FileEng ); 51 52// FileOutput.xml をテキストモード(UTF-8) で書き込みファイルとして開く 53objStreamOUT = new ActiveXObject( "ADODB.Stream" ); 54objStreamOUT.Type = adTypeText; 55objStreamOUT.charset = "utf-8"; 56objStreamOUT.Open(); 57 58while ( !objStreamEN.EOS ) { // ベースとなる「FileEnglish.xml」がなくなるまで読む 59strTextEN = objStreamEN.readText( adReadLine ); 60 if( strTextEN.match( regDescEn1 ) ) { 61 // 「FileEnglish.xml」内に<description>の開始タグが見つかった場合次を実行 62 while( strTextEN.match( regDescEn2 )){ 63 //</description>が見つかるまで以下を繰り返す 64 arrayEN.push(strTextEN) ;//読んだ内容を配列に入れる 65 strTextEN = objStreamEN.readText( adReadLine ); 66 } 67 arrayEN.push(strTextEN) ;//whileを抜けた後の</desc~>を配列に入れる 68 strTextEN = arrayEN.join('')//FileENの<desc~>から</desc~>の配列を結合して置き換える 69 70 adReadLineJA = -2; //FileJAの読み込み行をリセット 71 while( !objStreamJA.EOS ) { // 「FileJapanese.xml」の読み込みを開始 72 strTextJA = objStreamJA.readText( adReadLine ); //FileJAから一行ずつ読み込む 73 if( strTextJA.match( regDescEn1)){ //FileJAに<desc~>を見つけた場合、文を作る 74 while( strTextJA.match( regDescEn2 )){ 75 //</description>が見つかるまで以下を繰り返す 76 arrayJA.push(strTextJA) ;//読んだ内容を配列に入れる 77 strTextJA = objStreamJA.readText( adReadLine ); 78 } 79 arrayJA.push(strTextJA) ;//whileを抜けた後最後の</desc~>を配列に入れる 80 strTextJA = arrayJA.join('')//FileENの<desc~>から</desc~>の配列を結合して置き換え 81 if(strTextJA.match(strTextEN)){ //FileENとFileJAの<desc~>を比較する 82 83 strTextENJA = objStreamJA.readText( adReadLine ); //一致したら次の行をstrTextENJAに入れる 84 strTextENJA = strTextENJA.replace( regStrENJA1, "$2" ); // strTextENJA から訳文だけ抽出 85 strTextENJA = strTextENJA.replace( regDescEn1, "$1" + strTextENJA ); 86 // strTextENJA の訳文を <description>から始まる文にする 87 while( strTextENJA.match (regStrENJA2)){ //</Japanese>が見つかるまで繰り返す 88 arrayENJA.push(strTextENJA); 89 strTextENJA = objStreamJA.readText( adReadLine ); 90 } 91 strTextENJA = strTextENJA.replace( regStrENJA1, "$1" ); // strTextENJA から訳文だけ抽出 92 strTextENJA = strTextENJA.replace( strTextENJA + regDescEn1, "$2" ); 93 // strTextENJA の訳文を </description>で終わる文にする 94 arrayENJA.push(strTextENJA);//whileを抜けた後最後の</Japanese>を配列に入れる 95 96 arrayENJA.forEach(function(value){ 97 objStreamOUT.WriteText( value, adWriteLine ); // 配列の内容をファイルに書き込む 98 }); 99 arrayEN = new Array(); //配列ENを空に 100 decTotal++; // 置換件数を更新 101 break; //FileJapanese.xmlの読み込みを終了 102 } 103 } 104 //FileENとFileJAの<desc~>比較が一致しない場合、次の<desc~>を探して読み込みを続ける 105 } 106 } 107 if(arrayENJA.length > 1){ 108 arrayENJA = new Array(); 109 }else{ 110 if(arrayEN.length > 1){ 111 arrayEN.forEach(function(value){ 112 objStreamOUT.WriteText( value, adWriteLine ); // 配列の内容をファイルに書き込む 113 }); 114 arrayEN = new Array(); //配列ENを空に 115 } 116 else{ 117 objStreamOUT.WriteText( strTextEN, adWriteLine ); // 「FileOutput.xml」に一行(strTextENの内容を)追加 118 } 119 } 120 // objStreamOUT.WriteText( strTextEN, adWriteLine ); // 「FileOutput.xml」に一行(strTextENの内容を)追加 121 122 } 123 124// 処理完了後、ファイルを上書き保存 125objStreamOUT.SaveToFile( FileOutput, adSaveCreateOverWrite ); 126 127// 各ストリームを閉じる 128objStreamOUT.Close(); 129objStreamJA.Close(); 130objStreamEN.Close(); 131 132WScript.Echo( decTotal + " 件更新しました." ); 133WScript.Quit( 0 ); 134// ここまで「Test.js」

試したこと

  • もともとは知恵袋に投稿されていた例を使って作ろうとしているのですが、上記のような問題に当たったところです。

例題のソースは https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q10130543895 
から取得しました。

  • いろんなサイトの情報を元に組み立てたプログラムで、かなりぐちゃぐちゃだと思います

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

  • Microsoft Visual Studio Codeを使用して作成しています

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

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

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

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

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

guest

回答2

0

まずぱっと見でおかしいのは

new Array();とすべきを
new array();と小文字になっているところ。

まずは直して変わるか確認してください。

投稿2019/04/29 13:45

oikashinoa

総合スコア2826

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

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

l_kotomai

2019/04/30 02:26

回答ありがとうございます。全部の箇所をnew Array();と直しましたが、エラーは変わらないですね。。
oikashinoa

2019/04/30 04:13

> 111行目(arrayEN.forEach(function(value){)でエラー「オブジェクトでサポートされていないプロパティまたはメソッドです」が表示されて中断する TareTailのソースだと107行目ですかね? .forEachは配列が持っているメソッドですが、arrayENが途中(もしくは最初)から配列ではない可能性が有ります。 1. 上記行以外でエラーは無いのでしょうか?あるなら先に潰して下さい。 2. 上記行はwhile内で実行してますが、実行1回めで同じエラーになりますか? 3. そもそも上記行でarrayENは期待している内容ですか?(配列になっている?値の中身は期待通り?) typeof など使って確認してみて下さい Windows環境無いので動かしてあげること出来ず、回答できるのはこのくらいですね。
l_kotomai

2019/04/30 07:28

文字数制限のためにコメント行を潰したりしたので、手持ちのソースと行数変わったかもしれません。 エラーが起きるのは }else{ if(arrayEN.length > 1){ arrayEN.forEach(function(value){ の部分です。 1.あると思います。自分でも完全に理解できてないので。。 2.elseのすぐ下にWScript.EchoでArray3つの内容を表示してみてみましたが、Whileを6回経過した時点で、ArrayENには、FileEnglish.xmlの6行目に当たる、<description>の一行目が入っているのが確認できました。 ただ本来なら</description>まで複数行が入ってないといけないのですが。 同じ回数のArrayJAにはFileEnglishにある、3カ所の<description>開始タグのある行の一行目をそれぞれ、配列に入れたような内容が入っていました。 3.上記の通りArrayENの内容は期待とは違いますね。。 ここに来る前の<description>を見つけた後からのwhile以降に問題がありそうです
l_kotomai

2019/04/30 07:33 編集

追記 typeofでは3つのarrayともにobjectとでました
oikashinoa

2019/04/30 09:44 編集

⇡ごめんなさい typeofではなく、以下のどちらかで配列なのか確認して下さい。 console.log(Array.isArray(確認したい変数)); console.log(確認したい変数 instanceof Array ); で、そもそもプログラムの構造を見直すのも有りかと。シンプルにしませんか? 大別すると 1. FileJapanese.xmlのファイルを1行づつ読み込んで日本語、英語の対比用の配列を作る。 2. FileJapanese.xmlのファイルを1行づつ読み込んで上の対比用配列と照らしあわせて翻訳しファイルに出力する。 今までやってきた<description>〜</description>を考慮したロジックは必要です。 1が正しく動くのを確認してから2を作っていくと、問題点がはっきりしやすいです もしくはXMLをDOMとして扱ったほうが楽かもしれないです。 - js XML パース とかで調べてみて下さい - 何万行とか多いのでなければ此方のほうが楽かも。
l_kotomai

2019/05/01 06:42

詳しくありがとうございます。自分でもよく分からなかったんですが、今使ってるのはWSHのJScriptでforEachとか動かないみたいです..? しばらく時間がとれそうにないので改良には時間がかかりすそうです..
guest

0

多分ですが、この辺りが原因かと思います。どのように解決するかはわかりませんが。

Active​XObject(
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Microsoft_Extensions/ActiveXObject)

Important: ActiveX objects may present security issues. To use the ActiveXObject, you may need to adjust security settings in Internet Explorer for the relevant security zone. For example, for the local intranet zone, you typically need to change a custom setting to "Initialize and script ActiveX controls not marked as safe for scripting."

投稿2019/04/29 12:48

urbainleverrier

総合スコア200

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

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

l_kotomai

2019/04/30 02:32

読んではみましたが何が問題なのか分からないです。 if(arrayENJA.length > 1){ 以降でどのデータを書き込むか選択しているのですが、そこを全部なくして、読んだ内容をすべて別のファイルに書き込むのはできるみたいです。 arrayENに入っているデータが問題になっている気もしますが。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問