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 【问题描述】:

我们有一个复杂的 Adob​​e 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,我还能做什么?如何使用 Adob​​e 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=&apos;"),"&apos;")' />
            <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>

输出匹配您的第一个文件。如何将它与 Adob​​e 集成 - 我不知道...

【讨论】:

谢谢...一切都很好,除了照片部分。如果您检查第二个 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的主要内容,如果未能解决你的问题,请参考以下文章

在 Livecycle 表单中,将所有负值变为红色

将 XSD 选择元素表示为 LiveCycle Designer PDF 表单

Livecycle:在重复的子表单中引用对象

在 LiveCycle 中的实例上修改字段

您可以在 Adob​​e LiveCycle Designer 中复制动作吗?

JBoss 中的 JNDI 绑定(LiveCycle 统包)