幫助 XML 解析全部,
這與論壇上的另一個問題有關( https://community.jmp.com/t5/Discussions/Can-JMP-Support-Excel-Formatting-through-JSL/mp/86355#M38495 )。 我提供了一個非常大的 XML 檔案(Excel 中工作表的 XML)的一小部分。 我希望看到一個關於如何遍歷 XML 樹以有效地獲取目標元素的好範例。 有人可以提供一個很好的範例,說明使用 Parse XML 或 JSL 中的不同函數來取得值句柄的最佳方法是什麼和編輯值?
<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() ) ) ) ) )
);回覆:XML 解析幫助@gzmorgan0 ,
感謝您的詳細回覆。
客觀的:取得具有大量格式的大型 Excel 工作簿,並在不更改格式的情況下編輯工作表中的值。
到目前為止我遇到的選項:
- 使用 R 套件(例如 XLConnect(太慢)或 openxlsx(格式混亂且速度慢))
- 使用JSL
- 使用 JSL,迄今為止我遇到的保留格式的唯一可行選項是基於 Ian 的建議,即利用 Excel 工作簿背後的 XML,這正是我正在嘗試做的。
- 可能有一種使用 XPath 查詢的方法,如下所示:
XPath Query("\[<C r="J6" s="48"><V>1</V></C>]\","//v/text()");它在單元格中傳回正確的值,但是問題在於如何在不執行全域替換的情況下替換該值。
- 按照您的建議,使用 VB 腳本和執行程式。
由於sheet1 背後的XML 非常大(100,000 行或更多),因此我使用了一個小片段來提供一個範例,以尋求社群幫助我如何有效地向下鑽取層次結構。 我希望將整個解決方案保留在 JSL 中並使其乾淨高效,但如果沒有其他選項來修改 XML,我似乎必須依賴其他程式。 您認為我還缺乏其他選擇嗎? 有沒有更好的方法來處理這個問題?
回覆:XML 解析幫助ps 對於您貼文中的 XML 片段,只有儲存格 A1 有值。 它是字串類型,您必須從文件中取得它的值“xl/sharedStrings.xml”
回覆:XML 解析幫助@uday_guntupalli從您之前的帖子和此電子郵件字串中,我仍然不確定您要做什麼? Excel 擁有其格式。我從一個xml 相關文件中進行了簡單的讀取,然後寫入該文件並保存了壓縮文件,當我在Excel 中打開它時,它說它已損壞,但當我選擇修復它的選項時, Excel 工作簿包含我更改的值。(也許我寫了一個公式單元格??)。
您是否嘗試使用大型 Excel 檔案作為資料庫進行讀寫?您是否正在嘗試更改格式?具體任務是什麼,包括範圍(大小、任務、更新到位、新增行、刪除行等)。
以下是從 Big Class.jmp、Iris.jmp 和 Semiconductor Capability.jmp 建立的 3 頁 XLSX 檔案中的一個 XML 檔案的片段。 這是第一張紙。需要注意的維度是 A1:E41,因為第一行是列名稱。 一旦找到TagsheetData,資料是按行和單元格組織的,不容易替換一列。另請注意,帶有字串的單元格具有額外的編碼 t =\!"s\!"表示它是一個字串,值是一個數字。如果您需要該字串值,則需要在檔案「xl/sharedStrings.xml」中尋找該字串值。 參考編號從 0 開始。對於這個簡單的 3 頁 Excel 文件,有 490 個唯一字串,字串 44 是“F”,字串 45 是“M”,代表性別。
如果您對閱讀和編寫 XML 感興趣,JSL Companion 第二版中有一節以及一些腳本和範例。 但對於我「認為」您正在嘗試做的事情,我不會使用 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>
回覆:XML 解析幫助
@uday_guntupalli寫道:
@Craige_Hales ,
這真的很有幫助。 我們是否可以嘗試利用具有明確結構的固有 XML 結構?
我問這個問題的原因是 - 雖然 Pat Regex 方法快速且高效,但我擔心它可能需要不斷更改腳本才能跟上來源 Excel 中的微小更改。 雖然針對屬性而不是字串可能更強大?
更新:當我開始建立解決方案時,我使用的 Pat Regex 操作越多,解決方案變得越慢。 它看起來不可擴展。 我至少有 20 個需要替換的字段,以及需要替換的 5 列中包含 8760 個值的時間序列。 目前,JMP 超過 8 個正規表示式操作,每個操作平均花費 3.25 秒,您能否推薦任何其他可擴展的替代方案。 另外,我在 Pat Regex 的末尾沒有得到 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
);
回覆:XML 解析幫助@Craige_Hales ,
這真的很有幫助。 我們是否可以嘗試利用具有明確結構的固有 XML 結構?
我問這個問題的原因是 - 雖然 Pat Regex 方法快速且高效,但我擔心它可能需要不斷更改腳本才能跟上來源 Excel 中的微小更改。 雖然針對屬性而不是字串可能更強大?
回覆: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);
它將用 42 替換 0。 它顯示舊值 (0)。再次運行它會顯示42。
我使用 \s+ 和 \s* 而不是一組硬編碼的空白字元。 後綴/前綴是從文件中捕獲的,包括文件的實際空白字符,因此唯一的更改應該是 0 -> 42。 中間位元 [^<]* 捕捉零個或多個不是 <(下一個標記的開頭)的字元。
請務必測試 patmatch() 的回傳碼。 如果它不是 1,則 XML 不再是模式所期望的。