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