幫助 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 Query:
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,因為第一行是列名。 找到 Tag sheetData 後,數據按行和單元格組織,不容易替換一列。還要注意帶有字符串的單元格有額外的編碼 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>
回复:幫助 XML 解析
@uday_guntupalli寫道:
@Craige_Hales ,
這真的很有幫助。 我們可以嘗試利用具有良好定義結構的固有 XML 結構嗎?
我問這個問題的原因是 - 雖然 Pat Regex 方法快速有效,但我擔心它可能需要不斷更改腳本才能跟上源 Excel 中的微小變化。 雖然定位屬性而不是字符串可能更健壯?
更新:當我開始構建我的解決方案時,我使用的 Pat Regex 操作越多,解決方案就會變得越慢。 它看起來不可擴展。 我有至少 20 個需要替換的字段以及 5 列中需要替換的 8760 個值的時間序列。 目前超過 8 種正則表達式操作,JMP 平均每次需要 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 不再是模式所期望的。