帮助 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 不再是模式所期望的。