gpt4 book ai didi

xml - 如何按内容对元素进行分组(XSLT 2.0)?

转载 作者:数据小太阳 更新时间:2023-10-29 02:32:07 25 4
gpt4 key购买 nike

-- 修改后的问题--

已经感谢所有提供潜在解决方案的人,但这些与我已经尝试过的一致,所以我想我应该更清楚。我稍微扩展了 XML 以使问题更加透明。

XML实际上是各种文件的汇编,包含翻译的内容,目的是得到一个统一的文档,只包含唯一的英文字符串,并且(经过人工审查和清理)每个字符串都有一个翻译的,所以它可以用于翻译内存库。这就是为什么它现在是一个包含大量冗余信息的大文件。

每一段行都包含英文母版(在文件中可以重复数十次)和翻译变体。在很多情况下,这很容易,因为所有翻译版本都是相同的,所以我最终会得到一行,但在其他情况下,它可能会更复杂。

所以,假设今天我有 10 行包含相同的英语内容 (#1)、2 种不同的德语变体、3 种不同的法语变体,而其余的语言环境我只需要一个变体:

1 Para 具有:1 EN/2 DE(v1 和 v2)/3 FR(v1、v2 和 v3)/...

这对我列表中的每个分组的唯一英语值重复

修改后的 XML:

<Books>
<!--First English String (#1) with number of potential translations -->
<Para>
<EN>English Content #1</EN>
<DE>German Trans of #1 v1</DE>
<FR>French Trans of #1 v1</FR>
<!-- More locales here -->
</Para>
<Para>
<EN>English Content #1</EN>
<DE>German Trans of #1 v2</DE>
<FR>French Trans of #1 v1</FR>
<!-- More locales here -->
</Para>
<Para>
<EN>English Content #1</EN>
<DE>German Trans of #1 v1</DE>
<FR>French Trans of #1 v2</FR>
<!-- More locales here -->
</Para>
<!--Second English String (#2) with number of potential translations -->
<Para>
<EN>English Content #2</EN>
<DE>German Trans of #2 v1</DE>
<FR>French Trans of #2 v1</FR>
<!-- More locales here -->
</Para>
<Para>
<EN>English Content #2</EN>
<DE>German Trans of #2 v3</DE>
<FR>French Trans of #2 v1</FR>
<!-- More locales here -->
</Para>
<Para>
<EN>English Content #2</EN>
<DE>German Trans of #2 v2</DE>
<FR>French Trans of #2 v1</FR>
<!-- More locales here -->
</Para>
<!--Loads of additional English Strings (#3 ~ #n) with number of potential translations -->

当前的解决方案为我提供了以下输出

<Books>
<Para>
<EN>English Content #1</EN>
<DE>German Trans of #1 v1</DE>
<DE>German Trans of #1 v2</DE>
<DE>German Trans of #2 v1</DE>
<DE>German Trans of #2 v3</DE>
<DE>German Trans of #2 v2</DE>
<FR>French Trans of #1 v1</FR>
<FR>French Trans of #1 v1</FR>
<FR>French Trans of #1 v2</FR>
<FR>French Trans of #2 v1</FR>
</Para>
</Books>

因此,只取第一个 EN 标签,然后将所有其他标签分组,与英文主字符串之间的差异无关。虽然我的目标是获得以下内容:

<Books>
<!-- First Grouped EN string and linked grouped translations -->
<Para>
<EN>English Content #1</EN>
<DE>German Trans of #1 v1</DE>
<DE>German Trans of #1 v2</DE>
<FR>French Trans of #1 v1</FR>
<FR>French Trans of #1 v2</FR>
</Para>
<!-- Second Grouped EN string and linked grouped translations -->
<Para>
<EN>English Content #2</EN>
<DE>German Trans of #2 v1</DE>
<DE>German Trans of #2 v3</DE>
<DE>German Trans of #2 v2</DE>
<FR>French Trans of #2 v1</FR>
</Para>
<!-- 3d to n Grouped EN string and linked grouped translations -->
</Books>

最佳答案

扩展 XSLT 2.0 答案以完成问题请求中的更新

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="Books">
<xsl:copy>
<xsl:for-each-group select="*"
group-by="EN">
<xsl:copy>
<xsl:copy-of select="EN"/>
<xsl:for-each-group select="current-group()/*[not(local-name()='EN')]"
group-by=".">
<xsl:sort select="local-name()"/>
<xsl:copy-of select="."/>
</xsl:for-each-group>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

扩展 XSLT 1.0 答案以完成问题请求中的更新

即使您需要两种不同类型的 key ,您仍然可以使用相同类型的解决方案。这是第一个想到的简单解决方案:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="main" match="Para" use="EN"/>
<xsl:key name="locale" match="Para/*[not(self::EN)]" use="concat(../EN,.)"/>

<xsl:template match="Books">
<xsl:copy>
<xsl:apply-templates select="Para[
generate-id()
= generate-id(key('main',EN)[1])]" mode="EN"/>
</xsl:copy>
</xsl:template>

<xsl:template match="*" mode="EN">
<xsl:copy>
<xsl:copy-of select="EN"/>
<xsl:apply-templates select="../Para/*[
generate-id()
= generate-id(key('locale',concat(current()/EN,.))[1])]" mode="locale">
<xsl:sort select="local-name()"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>

<xsl:template match="*" mode="locale">
<xsl:copy>
<xsl:value-of select="."/>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

应用时

n the new provided input, produces:

<Books>
<Para>
<EN>English Content #1</EN>
<DE>German Trans of #1 v1</DE>
<DE>German Trans of #1 v2</DE>
<FR>French Trans of #1 v1</FR>
<FR>French Trans of #1 v2</FR>
</Para>
<Para>
<EN>English Content #2</EN>
<DE>German Trans of #2 v1</DE>
<DE>German Trans of #2 v3</DE>
<DE>German Trans of #2 v2</DE>
<FR>French Trans of #2 v1</FR>
</Para>
</Books>

此 XSLT 1.0 转换完全符合您的要求,如果您愿意,它可以用作创建更有意义的结果树的起点:

 <xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>


<xsl:key name="locale" match="Para/*[not(local-name()='EN')]" use="text()"/>

<xsl:template match="Books">
<xsl:copy>
<Para>
<xsl:copy-of select="Para[1]/EN"/>
<xsl:apply-templates select="Para/*[
generate-id()
= generate-id(key('locale',text())[1])]" mode="group">
<xsl:sort select="local-name()"/>
</xsl:apply-templates>
</Para>
</xsl:copy>
</xsl:template>

<xsl:template match="*" mode="group">
<xsl:copy>
<xsl:value-of select="."/>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

解释:

  • xsl:key 用于按内容对所有元素进行分组(但 EN)
  • 第一个PARA/EN节点的简单直接复制
  • Meunchian 分组方法xsl:sort 输出按要求分组的其他元素(具有相同内容的元素报告一次)

当应用于问题中提供的输入时,结果树是:

<Books>
<Para>
<EN>Some English Content</EN>
<DE>German Trans v1</DE>
<DE>German Trans v2</DE>
<FR>French Trans v1</FR>
<FR>French Trans v2</FR>
</Para>
</Books>

与 XSLT 2.0 xsl:for-each-group 相同的结果(和更短的转换):

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="Books">
<xsl:copy>
<Para>
<xsl:copy-of select="Para[1]/EN"/>
<xsl:for-each-group select="Para/*[not(local-name()='EN')]"
group-by=".">
<xsl:sort select="local-name()"/>
<xsl:copy>
<xsl:value-of select="."/>
</xsl:copy>
</xsl:for-each-group>
</Para>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>

关于xml - 如何按内容对元素进行分组(XSLT 2.0)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6486761/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com