使用 XSLT 将动态 XML 转换为 Adobe InDesign table
transform dynamic XML to Adobe InDesign table using XSLT
我在将 XML 项目列表转换为 indesign-table 时遇到了麻烦。一个问题是计算行数,因为这是需要的,但不能像简单的 count() 那样处理。
InDesign-table 应该是这样的:
+------------+-------------+------------+
|ARTIKELNR |BEZEICHNUNG |VK1BRUTTO |
+------------+-------------+------------+
| |TEXT1 |
+------------+--------------------------+
...
XML 看起来像这样:
<?xml version="1.0" encoding="iso-8859-1" standalone="yes"?>
<kategorie>
<artikel>
<ARTIKELNR> 200151</ARTIKELNR>
<BEZEICHNUNG>ARTIST ONE - the first release</BEZEICHNUNG>
<TEXT1></TEXT1>
<VK1BRUTTO>13,9900</VK1BRUTTO>
</artikel>
<artikel>
<ARTIKELNR> 200153</ARTIKELNR>
<BEZEICHNUNG>ARTIST TWO - the second release</BEZEICHNUNG>
<TEXT1>Lorem ipsum dolor whatever...</TEXT1>
<VK1BRUTTO>13,9900</VK1BRUTTO>
</artikel>
....
如您所见,有时 TEXT1 是空的。在这种情况下:此项没有第二行。
因此我写下了这个 (InDesign)XSLT:
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:aid="http://ns.adobe.com/AdobeInDesign/4.0/" xmlns:aid5="http://ns.adobe.com/AdobeInDesign/5.0/" exclude-result-prefixes="xs">
<xsl:output method="xml" encoding="utf-8" indent="no"/>
<xsl:strip-space elements="ARTIKELNR"/>
<xsl:template name="rowcount">
<xsl:param name="rows"/>
<xsl:for-each select="article">
<xsl:if test="TEXT1 != ''">
<xsl:call-template name="rowcount">
<xsl:with-param name="rows" select="$rows + 1" />
</xsl:call-template>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template match="/kategorie">
<xsl:variable name="rows"><xsl:call-template name="rowcount"/>
/xsl:variable>
<Table aid:tcols="3" aid:trows="$rows" aid:table="table" xmlns:aid="http://ns.adobe.com/AdobeInDesign/4.0/" xmlns:aid5="http://ns.adobe.com/AdobeInDesign/5.0/">
<xsl:for-each select="artikel">
<cell aid:table="cell" aid:crows="1" aid:ccols="1" aid:ccolwidth="25.30pt" aid:pstyle="abs_Produkt_Artikelnummer" aid:cstyle="zei_Produkt_Artikelnummer" aid5:cellstyle="zel_Produkt_Artikelnummer" aid:theader="">
<xsl:value-of select="substring(ARTIKELNR, string-length(ARTIKELNR) - 6)"/>
</cell>
<cell aid:table="cell" aid:crows="1" aid:ccols="1" aid:ccolwidth="136.76pt" aid:pstyle="abs_Produkt_Bezeichnung" aid:cstyle="zei_Produkt_Bezeichnung" aid5:cellstyle="zel_Produkt_Bezeichnung" aid:theader="">
<xsl:value-of select="BEZEICHNUNG"/>
</cell>
<cell aid:table="cell" aid:crows="1" aid:ccols="1" aid:ccolwidth="21.55pt" aid:pstyle="abs_Produkt_VKBrutto" aid:cstyle="zei_Produkt_VKBrutto" aid5:cellstyle="zel_Produkt_VKBrutto" aid:theader="">
<xsl:value-of select="substring(VK1BRUTTO, string-length(VK1BRUTTO), string-length(VK1BRUTTO)-2)"/>
</cell>
<xsl:variable name="freitext" select="TEXT1"/>
<xsl:if test="$freitext != ''">
<cell aid:table="cell" aid:crows="1" aid:ccols="1" aid:pstyle="abs__empty" aid:cstyle="zei__empty" aid5:cellstyle="zel__empty" aid:theader="">
</cell>
<cell aid:table="cell" aid:crows="1" aid:ccols="2" aid:pstyle="abs_Produkt_Beschreibung" aid:cstyle="zei_Produkt_Beschreibung" aid5:cellstyle="zel_Produkt_Beschreibung" aid:theader="">
<xsl:value-of select="TEXT1"/>
</cell>
</xsl:if>
</xsl:for-each>
</Table>
</xsl:template>
</xsl:stylesheet>
失败:
1.行数计算不正确。
2. InDesign 不会根据其结果构建 table。
谁能解释一下问题出在哪里,也许能给我一个正确的代码?
如果我没猜错的话,你想做这样的事情(省略不相关的属性):
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:aid="http://ns.adobe.com/AdobeInDesign/4.0/"
xmlns:aid5="http://ns.adobe.com/AdobeInDesign/5.0/">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/kategorie">
<Table aid:tcols="3" aid:trows="{count(artikel) + count(artikel/TEXT1[text()])}">
<xsl:for-each select="artikel">
<cell>
<xsl:value-of select="normalize-space(ARTIKELNR)"/>
</cell>
<cell>
<xsl:value-of select="BEZEICHNUNG"/>
</cell>
<cell>
<xsl:value-of select="VK1BRUTTO"/>
</cell>
<xsl:if test="TEXT1/text()">
<cell/>
<cell>
<xsl:value-of select="TEXT1"/>
</cell>
<cell/>
</xsl:if>
</xsl:for-each>
</Table>
</xsl:template>
</xsl:stylesheet>
应用于您的输入示例,结果将是:
<?xml version="1.0" encoding="UTF-8"?>
<Table xmlns:aid="http://ns.adobe.com/AdobeInDesign/4.0/" xmlns:aid5="http://ns.adobe.com/AdobeInDesign/5.0/" aid:tcols="3" aid:trows="3">
<cell>200151</cell>
<cell>ARTIST ONE - the first release</cell>
<cell>13,9900</cell>
<cell>200153</cell>
<cell>ARTIST TWO - the second release</cell>
<cell>13,9900</cell>
<cell/>
<cell>Lorem ipsum dolor whatever...</cell>
<cell/>
</Table>
谢谢。还有一些 "magic",我做到了:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:aid="http://ns.adobe.com/AdobeInDesign/4.0/" xmlns:aid5="http://ns.adobe.com/AdobeInDesign/5.0/">
<xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes"/>
<xsl:template match="/kategorie">
<Produkte>
<Tabelle aid:table="table" aid:tcols="3" aid:trows="{count(artikel) + count(artikel/TEXT1[text()])}" xmlns:aid="http://ns.adobe.com/AdobeInDesign/4.0/" xmlns:aid5="http://ns.adobe.com/AdobeInDesign/5.0/">
<xsl:for-each select="artikel">
<cell aid:table="cell" aid:ccolwidth="25.30" aid:pstyle="abs_Produkt_Artikelnummer" aid:cstyle="zei_Produkt_Artikelnummer" aid5:cellstyle="zel_Produkt_Artikelnummer" >
<xsl:value-of select="normalize-space(ARTIKELNR)"/>
</cell>
<cell aid:table="cell" aid:ccolwidth="136.76" aid:pstyle="abs_Produkt_Bezeichnung" aid:cstyle="zei_Produkt_Bezeichnung" aid5:cellstyle="zel_Produkt_Bezeichnung">
<xsl:value-of select="BEZEICHNUNG"/>
</cell>
<cell aid:table="cell" aid:ccolwidth="21.55" aid:pstyle="abs_Produkt_VKBrutto" aid:cstyle="zei_Produkt_VKBrutto" aid5:cellstyle="zel_Produkt_VKBrutto">
<xsl:value-of select="substring(VK1BRUTTO, 0, string-length(VK1BRUTTO)-1)"/>
</cell>
<xsl:if test="TEXT1/text()">
<cell aid:table="cell" aid:ccolwidth="25.30" aid:cstyle="zei_Produkt" aid5:cellstyle="zel_Produkt"></cell>
<cell aid:table="cell" aid:ccolwidth="158.31" aid:ccols="2" aid:pstyle="abs_Produkt_Beschreibung" aid:cstyle="zei_Produkt_Beschreibung" aid5:cellstyle="zel_Produkt_Beschreibung">
<xsl:value-of select="TEXT1"/>
</cell>
</xsl:if>
</xsl:for-each>
</Tabelle>
</Produkte>
</xsl:template>
</xsl:stylesheet>
提示:为了能够在 InDesign 中放置 table,table 周围必须有一个伪对象(即 "Produkte")。
约翰内斯
我在将 XML 项目列表转换为 indesign-table 时遇到了麻烦。一个问题是计算行数,因为这是需要的,但不能像简单的 count() 那样处理。
InDesign-table 应该是这样的:
+------------+-------------+------------+ |ARTIKELNR |BEZEICHNUNG |VK1BRUTTO | +------------+-------------+------------+ | |TEXT1 | +------------+--------------------------+ ...
XML 看起来像这样:
<?xml version="1.0" encoding="iso-8859-1" standalone="yes"?>
<kategorie>
<artikel>
<ARTIKELNR> 200151</ARTIKELNR>
<BEZEICHNUNG>ARTIST ONE - the first release</BEZEICHNUNG>
<TEXT1></TEXT1>
<VK1BRUTTO>13,9900</VK1BRUTTO>
</artikel>
<artikel>
<ARTIKELNR> 200153</ARTIKELNR>
<BEZEICHNUNG>ARTIST TWO - the second release</BEZEICHNUNG>
<TEXT1>Lorem ipsum dolor whatever...</TEXT1>
<VK1BRUTTO>13,9900</VK1BRUTTO>
</artikel>
....
如您所见,有时 TEXT1 是空的。在这种情况下:此项没有第二行。
因此我写下了这个 (InDesign)XSLT:
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:aid="http://ns.adobe.com/AdobeInDesign/4.0/" xmlns:aid5="http://ns.adobe.com/AdobeInDesign/5.0/" exclude-result-prefixes="xs">
<xsl:output method="xml" encoding="utf-8" indent="no"/>
<xsl:strip-space elements="ARTIKELNR"/>
<xsl:template name="rowcount">
<xsl:param name="rows"/>
<xsl:for-each select="article">
<xsl:if test="TEXT1 != ''">
<xsl:call-template name="rowcount">
<xsl:with-param name="rows" select="$rows + 1" />
</xsl:call-template>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template match="/kategorie">
<xsl:variable name="rows"><xsl:call-template name="rowcount"/>
/xsl:variable>
<Table aid:tcols="3" aid:trows="$rows" aid:table="table" xmlns:aid="http://ns.adobe.com/AdobeInDesign/4.0/" xmlns:aid5="http://ns.adobe.com/AdobeInDesign/5.0/">
<xsl:for-each select="artikel">
<cell aid:table="cell" aid:crows="1" aid:ccols="1" aid:ccolwidth="25.30pt" aid:pstyle="abs_Produkt_Artikelnummer" aid:cstyle="zei_Produkt_Artikelnummer" aid5:cellstyle="zel_Produkt_Artikelnummer" aid:theader="">
<xsl:value-of select="substring(ARTIKELNR, string-length(ARTIKELNR) - 6)"/>
</cell>
<cell aid:table="cell" aid:crows="1" aid:ccols="1" aid:ccolwidth="136.76pt" aid:pstyle="abs_Produkt_Bezeichnung" aid:cstyle="zei_Produkt_Bezeichnung" aid5:cellstyle="zel_Produkt_Bezeichnung" aid:theader="">
<xsl:value-of select="BEZEICHNUNG"/>
</cell>
<cell aid:table="cell" aid:crows="1" aid:ccols="1" aid:ccolwidth="21.55pt" aid:pstyle="abs_Produkt_VKBrutto" aid:cstyle="zei_Produkt_VKBrutto" aid5:cellstyle="zel_Produkt_VKBrutto" aid:theader="">
<xsl:value-of select="substring(VK1BRUTTO, string-length(VK1BRUTTO), string-length(VK1BRUTTO)-2)"/>
</cell>
<xsl:variable name="freitext" select="TEXT1"/>
<xsl:if test="$freitext != ''">
<cell aid:table="cell" aid:crows="1" aid:ccols="1" aid:pstyle="abs__empty" aid:cstyle="zei__empty" aid5:cellstyle="zel__empty" aid:theader="">
</cell>
<cell aid:table="cell" aid:crows="1" aid:ccols="2" aid:pstyle="abs_Produkt_Beschreibung" aid:cstyle="zei_Produkt_Beschreibung" aid5:cellstyle="zel_Produkt_Beschreibung" aid:theader="">
<xsl:value-of select="TEXT1"/>
</cell>
</xsl:if>
</xsl:for-each>
</Table>
</xsl:template>
</xsl:stylesheet>
失败: 1.行数计算不正确。 2. InDesign 不会根据其结果构建 table。
谁能解释一下问题出在哪里,也许能给我一个正确的代码?
如果我没猜错的话,你想做这样的事情(省略不相关的属性):
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:aid="http://ns.adobe.com/AdobeInDesign/4.0/"
xmlns:aid5="http://ns.adobe.com/AdobeInDesign/5.0/">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/kategorie">
<Table aid:tcols="3" aid:trows="{count(artikel) + count(artikel/TEXT1[text()])}">
<xsl:for-each select="artikel">
<cell>
<xsl:value-of select="normalize-space(ARTIKELNR)"/>
</cell>
<cell>
<xsl:value-of select="BEZEICHNUNG"/>
</cell>
<cell>
<xsl:value-of select="VK1BRUTTO"/>
</cell>
<xsl:if test="TEXT1/text()">
<cell/>
<cell>
<xsl:value-of select="TEXT1"/>
</cell>
<cell/>
</xsl:if>
</xsl:for-each>
</Table>
</xsl:template>
</xsl:stylesheet>
应用于您的输入示例,结果将是:
<?xml version="1.0" encoding="UTF-8"?>
<Table xmlns:aid="http://ns.adobe.com/AdobeInDesign/4.0/" xmlns:aid5="http://ns.adobe.com/AdobeInDesign/5.0/" aid:tcols="3" aid:trows="3">
<cell>200151</cell>
<cell>ARTIST ONE - the first release</cell>
<cell>13,9900</cell>
<cell>200153</cell>
<cell>ARTIST TWO - the second release</cell>
<cell>13,9900</cell>
<cell/>
<cell>Lorem ipsum dolor whatever...</cell>
<cell/>
</Table>
谢谢。还有一些 "magic",我做到了:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:aid="http://ns.adobe.com/AdobeInDesign/4.0/" xmlns:aid5="http://ns.adobe.com/AdobeInDesign/5.0/">
<xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes"/>
<xsl:template match="/kategorie">
<Produkte>
<Tabelle aid:table="table" aid:tcols="3" aid:trows="{count(artikel) + count(artikel/TEXT1[text()])}" xmlns:aid="http://ns.adobe.com/AdobeInDesign/4.0/" xmlns:aid5="http://ns.adobe.com/AdobeInDesign/5.0/">
<xsl:for-each select="artikel">
<cell aid:table="cell" aid:ccolwidth="25.30" aid:pstyle="abs_Produkt_Artikelnummer" aid:cstyle="zei_Produkt_Artikelnummer" aid5:cellstyle="zel_Produkt_Artikelnummer" >
<xsl:value-of select="normalize-space(ARTIKELNR)"/>
</cell>
<cell aid:table="cell" aid:ccolwidth="136.76" aid:pstyle="abs_Produkt_Bezeichnung" aid:cstyle="zei_Produkt_Bezeichnung" aid5:cellstyle="zel_Produkt_Bezeichnung">
<xsl:value-of select="BEZEICHNUNG"/>
</cell>
<cell aid:table="cell" aid:ccolwidth="21.55" aid:pstyle="abs_Produkt_VKBrutto" aid:cstyle="zei_Produkt_VKBrutto" aid5:cellstyle="zel_Produkt_VKBrutto">
<xsl:value-of select="substring(VK1BRUTTO, 0, string-length(VK1BRUTTO)-1)"/>
</cell>
<xsl:if test="TEXT1/text()">
<cell aid:table="cell" aid:ccolwidth="25.30" aid:cstyle="zei_Produkt" aid5:cellstyle="zel_Produkt"></cell>
<cell aid:table="cell" aid:ccolwidth="158.31" aid:ccols="2" aid:pstyle="abs_Produkt_Beschreibung" aid:cstyle="zei_Produkt_Beschreibung" aid5:cellstyle="zel_Produkt_Beschreibung">
<xsl:value-of select="TEXT1"/>
</cell>
</xsl:if>
</xsl:for-each>
</Tabelle>
</Produkte>
</xsl:template>
</xsl:stylesheet>
提示:为了能够在 InDesign 中放置 table,table 周围必须有一个伪对象(即 "Produkte")。
约翰内斯