XML 解析のヘルプ全て、
これはフォーラムの別の質問に関連しています ( https://community.jmp.com/t5/Discussions/Can-JMP-Support-Excel-Formatting-through-JSL/mp/86355#M38495 )。 私は非常に大きな XML ファイル (Excel のワークシートの XML) の小さなサブセットを提供しています。 XML ツリーをトラバースして目的の要素に効率的に到達する方法についての良い例を見てみたいと思います。 ここで値のハンドルを取得するために、JSL の Parse XML または別の関数を使用する最良の方法について、誰かが良い例を提供していただけますかそして値を編集しますか?
<C r="A1" s="67" t="s">
<V>0</V>
</C>
<WORKSHEET xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" mc="http://schemas.openxmlformats.org/markup-compatibility/2006" ignorable="x14ac" x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">
<DIMENSION ref="A1:BB101473"></DIMENSION>
<SHEETVIEWS>
<SHEETVIEW showgridlines="0" tabselected="1" zoomscalenormal="100" workbookviewid="0">
<SELECTION activecell="A13" sqref="A13"></SELECTION>
</SHEETVIEW>
</SHEETVIEWS>
<SHEETFORMATPR defaultrowheight="15" dydescent="0.25"></SHEETFORMATPR>
<COLS>
</COLS>
<SHEETDATA>
<ROW r="1" ht="24">
<C r="A1" s="67" t="s">
<V>0</V>
</C>
<C r="B1" s="67"></C>
<C r="C1" s="67"></C>
<C r="D1" s="67"></C>
<C r="E1" s="67"></C>
<C r="F1" s="67"></C>
<C r="G1" s="67"></C>
<C r="H1" s="67"></C>
<C r="I1" s="67"></C>
<C r="J1" s="67"></C>
<C r="K1" s="67"></C>
<C r="L1" s="67"></C>
<C r="M1" s="67"></C>
<C r="N1" s="10"></C>
<C r="O1" s="4"></C>
<C r="P1" s="4"></C>
<C r="Q1" s="4"></C>
<C r="R1" s="27"></C>
<C r="S1" s="27"></C>
<C r="T1" s="27"></C>
</ROW>
</SHEETDATA>
</WORKSHEET>次のことを試したところ、空のテーブルが得られました。
Parse XML(xml,
On Element("sheetData",Start Tag(New Table())),
On Element( "col", End Tag( New Column( XML Attr( "row r = '1' ht ='24'" ), Set Values( Parse( XML Text() ) ) ) ) )
);Re: XML 解析に関するヘルプ@gzmorgan0 、
詳細なご回答ありがとうございます。
客観的: 多くの書式設定が含まれる大きな Excel ワークブックを使用し、書式設定を変更せずにシート内の値を編集します。
これまでに出会ったオプション:
- R パッケージを使用します (XLConnect (遅すぎる) または openxlsx (フォーマットが混乱し、遅い) など)
- JSLを使用する
- JSL を使用して、書式設定を保持するためにこれまで私が見つけた唯一の実行可能なオプションは、Ian の提案に基づいています。つまり、Excel ワークブックの背後にある XML を利用することです。これが私がやろうとしていることです。
- XPath Query を次のように使用する方法があるかもしれません。
XPath Query("\[<C r="J6" s="48"><V>1</V></C>]\","//v/text()");セル内の正しい値が返されますが、問題は、グローバル置換を実行せずにこの値をどのように置き換えるかということです。
- 提案したように、プログラムの実行でVBスクリプトを使用します。
Sheet1 の背後にある XML は非常に大きい (100,000 行以上) ため、階層を効率的にドリルダウンする方法についてコミュニティの助けを求めるために、小さなスニペットを使用して例を提供しました。 ソリューション全体を JSL 内に保持し、クリーンで効率的なものにしたいと考えていましたが、XML を変更する他のオプションがない場合は、他のプログラムに依存する必要があるようです。 他に不足しているオプションがあると思いますか? この問題を処理するより良い方法はありますか?
Re: XML 解析に関するヘルプ投稿に含まれていた XML のスニペットについては、セル A1 のみに値がありました。 これは文字列型であり、ファイルから値を取得する必要があります。 「xl/sharedStrings.xml」
Re: XML 解析に関するヘルプ@uday_guntupalli以前の投稿とこのメール文字列からは、あなたが何をしようとしているのかまだわかりません。 Excel には独自の形式があります。1 つの XML 関連ファイルから単純な読み取りを行ってファイルに書き込み、圧縮ファイルを保存しました。Excel で開くと破損していると表示されましたが、修正するオプションを選択すると Excel ワークブックに変更された値が含まれていました。(もしかしたら数式セルに書き込んだかも??)。
大きな Excel ファイルを読み書き用のデータベースとして使用しようとしていますか?書式を変更しようとしていますか?スコープ (サイズ、タスク、所定の更新、行の追加、行の削除など) を含む特定のタスクとは何ですか。
以下は、Big Class.jmp、Iris.jmp、および Semiconductor Capability.jmp から作成された 3 シートの XLSX ファイル内の 1 つの XML ファイルのスニペットです。 これが最初のシートです。最初の行が列名であるため、次元は A1:E41 であることに注意してください。 タグシートデータを見つけると、データは行とセルごとに整理され、列を置き換えるのは簡単ではありません。また、文字列を含むセルには追加のコーディング t =\!"s\!" があることにも注意してください。これは、それが文字列であり、値が数値であることを示します。その文字列値が必要な場合は、ファイル「xl/sharedStrings.xml」でその文字列値を検索する必要があります。 参照番号は 0 から始まります。この単純な 3 シートの Excel ファイルには 490 個の一意の文字列があり、文字列 44 は「F」、文字列 45 は性別を表す「M」です。
XML の読み取りと書き込みに興味がある場合は、JSL Companion 2nd Edition のセクションといくつかのスクリプトと例を参照してください。 しかし、あなたがやろうとしていることについては、私は XML ではやりません。
"xl/worksheets/sheet1.xml"
"
<WORKSHEET xmlns="\!"http://schemas.openxmlformats.org/spreadsheetml/2006/main\!"" r="\!"http://schemas.openxmlformats.org/officeDocument/2006/relationships\!"" mc="\!"http://schemas.openxmlformats.org/markup-compatibility/2006\!"" ignorable="\!"x14ac" xr="" xr2="" xr3="">
<DIMENSION ref="\!"A1:E41\!"/">
<SHEETVIEWS><SHEETVIEW tabselected="\!"1\!"" workbookviewid="\!"0\!"/"></SHEETVIEW>
<SHEETFORMATPR defaultrowheight="\!"14.4\!"" dydescent="\!"0.3\!"/">
<COLS>
</COLS>
<SHEETDATA>
<ROW r="\!"1\!"" spans="\!"1:5\!"" ht="\!"18.600000000000001\!"" dydescent="\!"0.45\!"">
<C r="\!"A1\!"" s="\!"1\!"" t="\!"s\!""><V>0</V></C>
<C r="\!"B1\!"" s="\!"1\!"" t="\!"s\!""><V>1</V></C>
<C r="\!"C1\!"" s="\!"1\!"" t="\!"s\!""><V>2</V></C>
<C r="\!"D1\!"" s="\!"1\!"" t="\!"s\!""><V>3</V></C>
<C r="\!"E1\!"" s="\!"1\!"" t="\!"s\!""><V>4</V></C>
</ROW>
<ROW r="\!"2\!"" spans="\!"1:5\!"" dydescent="\!"0.3\!"">
<C r="\!"A2\!"" t="\!"s\!""><V>5</V></C>
<C r="\!"B2\!""><V>12</V></C>
<C r="\!"C2\!"" t="\!"s\!""><V>44</V></C>
<C r="\!"D2\!""><V>59</V></C>
<C r="\!"E2\!""><V>95</V></C>
</ROW></SHEETDATA></SHEETFORMATPR></SHEETVIEWS></DIMENSION></WORKSHEET>
Re: XML 解析に関するヘルプ
@uday_guntupalli書きました:
@Craige_Hales 、
これは本当に助かります。 明確に定義された構造を持つ固有の XML 構造を利用できるでしょうか?
私がこの質問をする理由は、Pat Regex アプローチは高速かつ効率的ですが、ソース Excel の微細な変更に対応するためにスクリプトを継続的に変更する必要があるのではないかと心配しているためです。 文字列ではなく属性をターゲットにした方がより堅牢になる可能性がありますが?
アップデート: ソリューションの構築を開始すると、使用する Pat Regex 操作が増えるほど、ソリューションの速度が遅くなります。 スケーラブルではないようです。 少なくとも 20 個のフィールドを置換する必要があり、さらに 5 つの列に 8760 個の時系列値を置換する必要があります。 現在、正規表現操作が 8 つ以上あり、JMP は各操作に平均 3.25 秒かかっています。他にスケーラブルな代替手段をお勧めしますか。 さらに、パット正規表現の最後に 1 が得られません。
x = char(10);
Pat Match(
xml, // source
Pat Regex( "\[<C>\s*<V>]\" ) >> prefix + // what comes before goes in prefix
Pat Regex( "[^<]*" ) >> old + // the middle part we care about, probably some digits
Pat Regex( "\[</V>\s*</C>]\" ) >> suffix, // what comes after goes in suffix
prefix || x|| suffix // replace the matched section with this
);
Re: XML 解析に関するヘルプ@Craige_Hales 、
これは本当に助かります。 明確に定義された構造を持つ固有の XML 構造を利用できるでしょうか?
私がこの質問をする理由は、Pat Regex アプローチは高速かつ効率的ですが、ソース Excel の微細な変更に対応するためにスクリプトを継続的に変更する必要があるのではないかと心配しているためです。 文字列ではなく属性をターゲットにするほうがより堅牢かもしれませんが?
Re: XML 解析に関するヘルプ他に XML を更新する必要がない場合は、少しのパターン マッチングを行うだけで XML を非常に単純に保つことができます。
Pat Match(
xml, // source
Pat Regex( "\[<C>\s*<V>]\" ) >> prefix + // what comes before goes in prefix
Pat Regex( "[^<]*" ) >> old + // the middle part we care about, probably some digits
Pat Regex( "\[</V>\s*</C>]\" ) >> suffix, // what comes after goes in suffix
prefix || "42" || suffix // replace the matched section with this
);
show(old);
これにより、0 が 42 に置き換えられます。 古い値 (0) が表示されます。もう一度実行すると 42 が表示されます。
ハードコードされた一連の空白文字ではなく、\s+ と \s* を使用しました。 サフィックス/プレフィックスは、ドキュメントの実際の空白文字を含めてドキュメントから取得されるため、唯一の変更は 0 -> 42 です。 中央のビット [^<]* は、< ではない一連の 0 個以上の文字 (次のタグの先頭) をキャプチャします。
patmatch() からの戻りコードを必ずテストしてください。 1 でない場合、XML はパターンが期待するものではなくなります。