问题描述
我有一个 xml 文件,它为 Workday 集成提供输入。输入是一个 xml 文件,通常在 Excel 中打开并通过粘贴 sql 查询的输出进行填充。但是,这个特定的 xml 需要填充超过 Excel 单元格大小限制的数据。单元格数据是 base64 编码的 .pdf 文件。一列中的每个单元格将包含一个 .pdf 文件的内容。
我能够创建用短文本字符串(“文件内容”)标记文件内容单元格的 xml,但我需要某种方式将这些标记替换为编码的文件内容。
我相信一定有工具可以做到这一点,但我对 xml 操作比较陌生。我想到的可能是 Powershell、xslt 或 Oxygen 应用程序之一,但我不知道哪一个是最好的(XML 编辑器?作者?)。附件是在 Excel 和 Oxygen 中打开的 xml 的图像。
解决方法
带有 EXPath 文件模块和 Saxon EE 的 XSLT 3 和流式传输在某种程度上与
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:file="http://expath.org/ns/file"
xpath-default-namespace="put excel namespace here"
exclude-result-prefixes="#all"
version="3.0">
<!-- adjust these integers to match the cell index of the real input -->
<xsl:param name="cell-index-file-name" as="xs:integer" select="3"/>
<xsl:param name="cell-index-file-contents" as="xs:integer" select="6"/>
<xsl:mode streamable="yes" on-no-match="shallow-copy" use-accumulators="#all"/>
<xsl:accumulator name="pos" as="xs:integer?" initial-value="()" streamable="yes">
<xsl:accumulator-rule match="Table" select="()"/>
<xsl:accumulator-rule match="Table/Row" select="0"/>
<xsl:accumulator-rule match="Table/Row/Cell" select="$value + 1"/>
</xsl:accumulator>
<xsl:accumulator name="file-name" as="xs:string?" initial-value="()" streamable="yes">
<xsl:accumulator-rule match="Row/Cell[accumulator-before('pos') eq $cell-index-file-name]/text()" select="data()"/>
</xsl:accumulator>
<xsl:template match="Row/Cell[accumulator-before('pos') eq $cell-index-file-contents]">
<xsl:copy>
<xsl:value-of select="file:read-binary(resolve-uri(accumulator-before('file-name')))"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>