Adobe LiveCycle:使用 XSLT 将 XML 转换为 XML
Posted
技术标签:
【中文标题】Adobe LiveCycle:使用 XSLT 将 XML 转换为 XML【英文标题】:Adobe LiveCycle: XML to XML Transformation using XSLT 【发布时间】:2019-12-05 18:19:47 【问题描述】:我们有一个复杂的 Adobe LiveCycle XDP (XFA) 用于带有 XML 数据模型的评估员申请表(默认一个,没什么特别的)。还有另一个 XDP 具有相同的 Application Form,相同的布局,但具有不同的模型和 XML 结构。第二种形式的XML结构是基于我不熟悉的格式,但我能理解其中的内容。
第一个 XML 是普通的 XML,直截了当。
第二个 XML 有多个嵌套部分,字段名称在标签元素的属性中指定。图片在附件部分中指定,并且是来自相关标签元素的引用。
以下是第一个 XML 的示例:
<app_rep1>
<NEW_primaryform>Some-primary-form</NEW_primaryform>
<NEW_TITLE_PHOTO>SamplePhotoLabel1</NEW_TITLE_PHOTO>
<NEW_CITY>Toronto</NEW_CITY>
<NEW_Stage>Stage Value</NEW_Stage>
<NEW_GS_AGE>23</NEW_GS_AGE>
<NEW_POOL_X>Nice Pool</NEW_POOL_X><NEW_PHOTO1>/9j/4AAQSkZJRgABAAEASABIAAD//gAfTEVBRCBUZWNobm9sb2dpZXMgSW5jLiBWMS4wMQD/2wCE
bla...bla...bla
</NEW_PHOTO1>
</app_rep1>
以下是第二个 XML 的示例:
<app_rep2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.1">
<appraisal>
<configuration>
<primaryform>Some-primary-form</primaryform>
<versioninfo>
<acifileversion>123</acifileversion>
<collectionversion>1.2.3.4</collectionversion>
<collection>Report Pro</collection>
<platform>Desktop Platform</platform>
</versioninfo>
</configuration>
<data>
<form name="photo1" primary="false">
<section type="other" number="0" name="section_name1">
<tag name="TITLE_PHOTO">SamplePhotoLabel1</tag>
<tag name="LINE_PHOTO">SamplePhotoDescription1</tag>
</section>
<tag name="PHOTO1">../../../attachments/attachment[@key='267463fa-0073-4c10-83d6-fd8141641b72']</tag>
</form>
<form name="Some-primary-form" primary="true">
<section type="other" number="0" name="OPTIONS">
<tag name="OPT_TYPE_OF_APPRAISAL">Appraisal Type Value</tag>
</section>
<section type="subject" number="0" name="SUBJECT">
<tag name="CITY">Toronto</tag>
<tag name="STATE">Stage Value</tag>
<tag name="GS_AGE">23</tag>
<tag name="POOL_X">Nice Pool</tag>
</section>
</form>
</data>
<attachments>
<attachment type="photo" label="" key="267463fa-0073-4c10-83d6-fd8141641b72">
<image>
<binary format="jpeg">/9j/4AAQSkZJRgABAAEASABIAAD//gAfTEVBRCBUZWNobm9sb2dpZXMgSW5jLiBWMS4wMQD/2wCE
bla...bla...bla
</binary>
</image>
</attachment>
</attachments>
</appraisal>
</app_rep2>
如您所见,我想将第二个 XML 转换为看起来像第一个 XML。
我想我需要先编写 XSLT。然后,我需要将第二个 XML 导入到第一个 XDP 中,并在导入时应用 XSLT。
我的想法是否正确?
您能帮我实现目标吗?我不确定该怎么做。
问题:
如何开发 XSLT?
如何在将第二个 XML 与第一个 XDP 合并时应用 XSLT?除了使用 Acrobat,我还能做什么?如何使用 Adobe LiveCycle Process Management 做到这一点?
如何执行字段名称从 XML 1 到 XML 2 的映射?有1000多个字段。我可以在 Excel 文件(field_name_1,field_name_2)中准备对列表,但是如何使用列表作为输入来应用查找/替换?因此,第 1 步将使用错误的字段名称应用转换,然后第 2 步将应用查找/替换。
任何帮助将不胜感激。
谢谢, 塔雷克
【问题讨论】:
我可以做映射,唯一的问题是遍历照片元素,谁的XPath是另一个元素的值。见tag name="PHOTO1"
。你能帮忙吗?
用文字来解决......我想要一个变量,它是 @key='[ 之后和 '[ 之前的值,然后找到其祖先附件具有该 @key 属性值的二进制文件与该变量相同。但是如果你需要导航附件/附件,因为它可能是 foo/bat,那么也写。
对不起,我没听懂你说的。我刚刚意识到这是 XSL 2.0 中的一个问题。这与动态评估 XPath 有关。您需要使用库。我找到了一对,但我无法实现它们。我尝试使用 freeformatter.com/xsl-transformer.html 和 np++,但它们都不起作用。请参阅此处的示例:blogs.it.ox.ac.uk/jamesc/2009/06/05/…
【参考方案1】:
关于问题的第一部分,您可以使用此 XSLT-1.0 样式表从 XML 中简单地提取值。 NEW_PHOTO1
元素的问题在于 XPath 的动态评估只能在 XSLT-3.0 中使用 xsl:evaluate
函数进行(并且 IIRC,您甚至需要 Saxon 的商业版本或支持它的其他处理器)。而且我不知道你提到的扩展库。
但是,如果您可以硬编码基本路径/app_rep2/appraisal/attachments/attachment
,则可以将tag
元素中的键与attachment
元素的键属性相匹配。这并不优雅,但可能会根据您的整个场景为您省去麻烦。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="app_rep2">
<app_rep1>
<NEW_primaryform><xsl:value-of select="appraisal/configuration/primaryform" /></NEW_primaryform>
<NEW_TITLE_PHOTO><xsl:value-of select="appraisal/data/form[@name='photo1']/section/tag[@name='TITLE_PHOTO']" /></NEW_TITLE_PHOTO>
<NEW_CITY><xsl:value-of select="appraisal/data/form[@name='Some-primary-form']/section[@type='subject']/tag[@name='CITY']" /></NEW_CITY>
<NEW_Stage><xsl:value-of select="appraisal/data/form[@name='Some-primary-form']/section[@type='subject']/tag[@name='STATE']" /></NEW_Stage>
<NEW_GS_AGE><xsl:value-of select="appraisal/data/form[@name='Some-primary-form']/section[@type='subject']/tag[@name='GS_AGE']" /></NEW_GS_AGE>
<NEW_POOL_X><xsl:value-of select="appraisal/data/form[@name='Some-primary-form']/section[@type='subject']/tag[@name='POOL_X']" /></NEW_POOL_X>
<xsl:variable name="key" select='substring-before(substring-after(appraisal/data/form[@name="photo1"]/tag[@name="PHOTO1"],"@key='"),"'")' />
<NEW_PHOTO1><xsl:value-of select="/app_rep2/appraisal/attachments/attachment[@type='photo' and @key=$key]/image/binary" /></NEW_PHOTO1>
</app_rep1>
</xsl:template>
</xsl:stylesheet>
输出匹配您的第一个文件。如何将它与 Adobe 集成 - 我不知道...
【讨论】:
谢谢...一切都很好,除了照片部分。如果您检查第二个 XML,您将看到照片的 XPath 是在元素app_rep2/appraisal/data/form[@name="photo1"]/tag[@name="PHOTO1"]
中指定的。你能告诉我如何从这个照片元素中读取 XPath,并遍历到新的 XPath 以访问 Base64 格式的二进制数据吗?
@tarekahf:我用替代解决方案更新了我的答案。
我认为你通过应用子字符串操作给了我解决方案,这是一个很棒的解决方案。我认为我不能使用外部库,因为它可能不受支持。你能帮我做一件事吗?这是关于将字段名称从 XML 1 映射到 XML 2,用于 1000 多个字段。我可以在 excel 文件中准备对 (field_name_1, field_name_2) 的列表,但是如何在转换后将其应用于结果 XML 文件?所以,第 1 步将生成具有错误名称的新 XML,第 2 步将执行查找/替换,但是如何?
@tarekahf:这是完全不同的问题,所以最好用一个好的样本提出一个新问题。第一步应该是将 Excel 数据导出到 XML 文件。以上是关于Adobe LiveCycle:使用 XSLT 将 XML 转换为 XML的主要内容,如果未能解决你的问题,请参考以下文章
将 XSD 选择元素表示为 LiveCycle Designer PDF 表单