我正在尝试转换这样的数据:
<word>
<morph type="prefix">
<item type="txt" lang="tmy-Latn">ne-</item>
<item type="gls" lang="en">3p.POSS-</item>
<item type="gls" lang="tpi" />
<item type="msa" lang="en">pro</item>
</morph>
<morph type="stem">
<item type="txt" lang="tmy-Latn">waŋ</item>
<item type="msa" lang="en">noun</item>
</morph>
</word>
<word>
<morph>
<item><item type="txt" lang="tmy-Latn">lil</item>
<item type="gls" lang="en">go</item>
<item type="msa" lang="en">verb</item>morph>
</word>
相关因素是有一堆<morph>
元素,每个元素都有各种子<item>
元素。问题是,对于任何给定的文档,某些类型的项元素可能完全不存在。有些可能仅存在于某些变形元素中。如果他们在场,他们可能是空的。最后,在一个变形元素中可能会有多个相同@type
的项目,但是它们的@lang
属性会有所不同。
当我转换文档时,我需要一种方法来了解该特定文档中存在哪些不同的项目元素 - 即基于@type
和@lang
的不同。因此,在上面的示例中,不同的项目将是:
最终我希望有一个for-each循环,对每个应存在的item
元素说(即上面列出的4个)创建一个段落,然后通过每个morph
元素,如果给定项目输出其内容,如果项目不存在,则输出任何内容或占位符文本,具体取决于项目类型。如果文档中没有项目类型,则不应该有任何段落。
我制作了一个文档,其中一切工作正常,但项目类型是硬编码的,并没有考虑到可能有多个相同类型的项目(但不同的lang)。我无法对lang进行硬编码。我这样做的方式我认为我需要完全重做它。我一直在努力从网上复制xsl:key和变量以及其他技巧的例子,但我没有得到它(我根本不知道XSLT)。
期望的输出(简化):
<word>
<p type="txt" lang="tmy-Latn">ne-waŋ</p>
<p type="gls" lang="en">3p.POSS-???</p>
<p type="gls" lang="tpi>???-???</p>
<p type="msa" lang="en">pro-noun</p>
</word>
<word>
<p type="txt" lang="tmy-Latn">lil</p>
<p type="gls" lang="en">go</p>
<p type="gls" lang="tpi>???</p>
<p type="msa" lang="en">verb</p>
</word>
请注意,每个单词中的morph
元素已按项目类型/ lang合并。如果此文档中预期有四种类型的空{或item
,则会插入三个问号。
基于Valdi_Bo答案的示例尝试:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" />
<xsl:key name="itemTypes" match="//item" use="@type"/>
<xsl:key name="items" match="//item" use="concat(@type, '/', @lang)"/>
<xsl:variable name="keys" select="//morph/item[generate-id()=
generate-id(key('items', concat(@type, '/', @lang))[1])]"/>
<xsl:template match="word">
<xsl:copy>
<xsl:for-each select="//item[generate-id()=generate-id(key('itemTypes', @type)[1])]">
<xsl:variable name="currentType" select="@type"/>
<xsl:for-each select="//item[generate-id()=generate-id(key('items', concat($currentType, '/', @lang))[1])]">
<p>
What do I put here?
</p>
</xsl:for-each>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:transform>
答案 0 :(得分:2)
您可以使用下面给出的脚本找到不同的项目“键”(键入/ lang)。
出于演示目的,此脚本从打印所有“源”开始 项目,按类型和 lang 排序。
然后是主要部分 - 创建项目列表(具有唯一的类型 / lang 属性)。
最后一部分包含刚刚创建的列表的2个演示文稿。
就源XML而言,我假设你的pip3 freeze
元素
如XML格式所需,它们位于单个 word
标记中。
这就是我的模板仅与root
元素匹配的原因。
root
有关工作示例,请参阅http://xsltransform.net/6q1R79v/1
从上面的脚本中你应该使用: