Xslt 分组*几乎*唯一ID
我正在努力将几乎相同的ID分组。基本上,我需要对PF.A1PF和PersIntr.personal.alpersonelative部分的内容进行分组,并在获取id之前剥离子字符串。我没有所有部分id的列表 请参见下面的示例 以下是当前的XML:Xslt 分组*几乎*唯一ID,xslt,Xslt,我正在努力将几乎相同的ID分组。基本上,我需要对PF.A1PF和PersIntr.personal.alpersonelative部分的内容进行分组,并在获取id之前剥离子字符串。我没有所有部分id的列表 请参见下面的示例 以下是当前的XML: <group> <section id="unique_1_Connect_42_PF.AlPF"> <msgph id="doc" xml:lang="en_US">It has been a externa
<group>
<section id="unique_1_Connect_42_PF.AlPF">
<msgph id="doc" xml:lang="en_US">It has been a external net failure. The pumps are
blocked.</msgph>
<msgph id="cstext" xml:lang="en_US">Mains error</msgph>
<msgph id="localtext" xml:lang="en_US">Mains error</msgph>
</section>
<section id="unique_1_Connect_42_PersIntr.Personnel.AlPersonnelActive">
<msgph id="doc" xml:lang="en_US">Personal alarm warning time has run out without reset.
Personnel in danger !</msgph>
<msgph id="cstext" xml:lang="en_US">Personal alarm</msgph>
<msgph id="localtext" xml:lang="en_US">Pers. alarm</msgph>
</section>
<section id="unique_2_Connect_42_PF.AlPF">
<msgph id="doc" xml:lang="es_ES">Ha habido un fallo de red externa. Las bombas están
bloquedas.</msgph>
<msgph id="cstext" xml:lang="es_ES">Fallo energía de entrada</msgph>
<msgph id="localtext" xml:lang="es_ES">Fallo energía</msgph>
</section>
<section id="unique_2_Connect_42_PersIntr.Personnel.AlPersonnelActive">
<msgph id="doc" xml:lang="es_ES">Tiempo de espera de la alarma de personal ha finalizado sin
reseteo. ¡Personal en peligro!</msgph>
<msgph id="cstext" xml:lang="es_ES">Alarma personal</msgph>
<msgph id="localtext" xml:lang="es_ES">Alarma personal</msgph>
</section>
这是一次外部网络故障。水泵是
此 路 不通。
电源错误
电源错误
个人警报警告时间已用完,无需重置。
有危险的人员!
个人报警器
佩尔斯。警报
红色外星法学院。拉斯邦巴斯埃斯坦酒店
布卢克达斯。
法罗能源公司
法洛能源公司
个人犯罪报警事件
雷塞奥。“私人恩佩利格罗!
个人警报
个人警报
以下是我需要输出的内容:
<Rsc Id="PF.AlPF">
<Documentation en_US="It has been a external net failure. The pumps are blocked."
es_ES="Ha habido un fallo de red externa. Las bombas están bloquedas."/>
<CSText en_US="Mains error" es_ES="Fallo energía de entrada"/>
<LocalText en_US="Mains error" es_ES="Fallo energía"/>
</Rsc>
<Rsc Id="PersIntr.Personnel.AlPersonnelActive">
<Documentation
en_US="Personal alarm warning time has run out without reset. Personnel in danger !"
es_ES="Tiempo de espera de la alarma de personal ha finalizado sin reseteo. ¡Personal en peligro!"/>
<CSText en_US="Personal alarm" es_ES="Alarma personal"/>
<LocalText en_US="Pers. alarm" es_ES="Alarma personal"/>
</Rsc>
我真的很感激你的洞察力。提前感谢您的关注
亲切问候,,
安妮
更新: 非常感谢,迪米特里,迈克尔。我真的很感谢你在这次挑战中的帮助。在2.0解决方案的这一部分中,我在元素解析方面遇到了一些问题:
<xsl:element name="{$vNewNames[starts-with(lower-case(.),current()/@id)]}">
<xsl:for-each select="current-group()">
<xsl:attribute name="{@xml:lang}" select="."/>
</xsl:for-each>
</xsl:element>
以下是最终奏效的方法:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<Resources>
<Type key="Alarm">
<xsl:for-each-group select="//section" group-by="substring-after(@id, '_42_')">
<xsl:variable name="currentID" select="substring-after(@id, '_42_')"/>
<xsl:element name="Rsc">
<xsl:attribute name="id" select="$currentID"/>
<xsl:for-each-group select="//section[$currentID]/msgph"
group-by="substring-after(@id, '_42_')">
<xsl:choose>
<xsl:when test="substring-after(@id, '_42_')='doc'">
<Documentation>
<xsl:for-each select="current-group()">
<xsl:if test="contains(parent::*/@id,$currentID)">
<xsl:attribute name="{@xml:lang}" select="."/>
</xsl:if>
</xsl:for-each>
</Documentation>
</xsl:when>
<xsl:when test="substring-after(@id, '_42_')='cstext'">
<CSText>
<xsl:for-each select="current-group()">
<xsl:if test="contains(parent::*/@id,$currentID)">
<xsl:attribute name="{@xml:lang}" select="."/>
</xsl:if>
</xsl:for-each>
</CSText>
</xsl:when>
<xsl:when test="substring-after(@id, '_42_')='localtext'">
<LocalText>
<xsl:for-each select="current-group()">
<xsl:if test="contains(parent::*/@id,$currentID)">
<xsl:attribute name="{@xml:lang}" select="."/>
</xsl:if>
</xsl:for-each>
</LocalText>
</xsl:when>
</xsl:choose>
</xsl:for-each-group>
</xsl:element>
</xsl:for-each-group>
</Type>
</Resources>
</xsl:template>
再次感谢!
Anne我对XSLT了解不多,但似乎您应该能够使用XSLT去掉每个节[id]的前22个字符并返回重要部分。我对XSLT了解不多,但似乎您应该能够使用XSLT去掉每个节[id]的前22个字符并返回重要部分。定义“几乎”。只有这样你才能想出一个合理的解决办法。然后,您很可能会使用基本的xslt函数自己解决这个问题 定义“几乎”。只有这样你才能想出一个合理的解决办法。然后,您很可能会使用基本的xslt函数自己解决这个问题 此转换:
<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="ksectById" match="section"
use="substring-after(@id, '42_')"/>
<xsl:template match=
"section[generate-id()
=
generate-id(key('ksectById',
substring-after(@id, '42_')
)[1]
)
]
">
<xsl:variable name="vId" select=
"substring-after(@id, '42_')"/>
<xsl:variable name="vGroup" select=
"key('ksectById',$vId)"/>
<Rsc Id="{$vId}">
<Documentation>
<xsl:apply-templates select=
"$vGroup/msgph[@id='doc']/@xml:lang"/>
</Documentation>
<CSText>
<xsl:apply-templates select=
"$vGroup/msgph[@id='cstext']/@xml:lang"/>
</CSText>
<LocalText>
<xsl:apply-templates select=
"$vGroup/msgph[@id='localtext']/@xml:lang"/>
</LocalText>
</Rsc>
</xsl:template>
<xsl:template match="@xml:lang">
<xsl:attribute name="{.}">
<xsl:value-of select=".."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="*/*" priority="-1"/>
</xsl:stylesheet>
<group>
<section id="unique_1_Connect_42_PF.AlPF">
<msgph id="doc" xml:lang="en_US">It has been a external net failure. The pumps are blocked.</msgph>
<msgph id="cstext" xml:lang="en_US">Mains error</msgph>
<msgph id="localtext" xml:lang="en_US">Mains error</msgph>
</section>
<section id="unique_1_Connect_42_PersIntr.Personnel.AlPersonnelActive">
<msgph id="doc" xml:lang="en_US">Personal alarm warning time has run out without reset. Personnel in danger !</msgph>
<msgph id="cstext" xml:lang="en_US">Personal alarm</msgph>
<msgph id="localtext" xml:lang="en_US">Pers. alarm</msgph>
</section>
<section id="unique_2_Connect_42_PF.AlPF">
<msgph id="doc" xml:lang="es_ES">Ha habido un fallo de red externa. Las bombas están bloquedas.</msgph>
<msgph id="cstext" xml:lang="es_ES">Fallo energía de entrada</msgph>
<msgph id="localtext" xml:lang="es_ES">Fallo energía</msgph>
</section>
<section id="unique_2_Connect_42_PersIntr.Personnel.AlPersonnelActive">
<msgph id="doc" xml:lang="es_ES">Tiempo de espera de la alarma de personal ha finalizado sin reseteo. ¡Personal en peligro!</msgph>
<msgph id="cstext" xml:lang="es_ES">Alarma personal</msgph>
<msgph id="localtext" xml:lang="es_ES">Alarma personal</msgph>
</section>
</group>
<Rsc Id="PF.AlPF">
<Documentation en_US="It has been a external net failure. The pumps are blocked." es_ES="Ha habido un fallo de red externa. Las bombas están bloquedas."/>
<CSText en_US="Mains error" es_ES="Fallo energía de entrada"/>
<LocalText en_US="Mains error" es_ES="Fallo energía"/>
</Rsc>
<Rsc Id="PersIntr.Personnel.AlPersonnelActive">
<Documentation en_US="Personal alarm warning time has run out without reset. Personnel in danger !" es_ES="Tiempo de espera de la alarma de personal ha finalizado sin reseteo. ¡Personal en peligro!"/>
<CSText en_US="Personal alarm" es_ES="Alarma personal"/>
<LocalText en_US="Pers. alarm" es_ES="Alarma personal"/>
</Rsc>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vNewNames" select=
"'Documentation', 'CSText', 'LocalText'"/>
<xsl:template match="/*">
<xsl:for-each-group select="section"
group-by="substring-after(@id, '_42_')">
<xsl:variable name="vId" select=
"substring-after(@id, '42_')"/>
<Rsc Id="{$vId}">
<xsl:for-each-group select="current-group()/*"
group-by="@id">
<xsl:element name=
"{$vNewNames[starts-with(lower-case(.),current()/@id)]}">
<xsl:for-each select="current-group()">
<xsl:attribute name="{@xml:lang}" select="."/>
</xsl:for-each>
</xsl:element>
</xsl:for-each-group>
</Rsc>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
此代码使用了一些非常强大和最自然的XSLT 2.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="ksectById" match="section"
use="substring-after(@id, '42_')"/>
<xsl:template match=
"section[generate-id()
=
generate-id(key('ksectById',
substring-after(@id, '42_')
)[1]
)
]
">
<xsl:variable name="vId" select=
"substring-after(@id, '42_')"/>
<xsl:variable name="vGroup" select=
"key('ksectById',$vId)"/>
<Rsc Id="{$vId}">
<Documentation>
<xsl:apply-templates select=
"$vGroup/msgph[@id='doc']/@xml:lang"/>
</Documentation>
<CSText>
<xsl:apply-templates select=
"$vGroup/msgph[@id='cstext']/@xml:lang"/>
</CSText>
<LocalText>
<xsl:apply-templates select=
"$vGroup/msgph[@id='localtext']/@xml:lang"/>
</LocalText>
</Rsc>
</xsl:template>
<xsl:template match="@xml:lang">
<xsl:attribute name="{.}">
<xsl:value-of select=".."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="*/*" priority="-1"/>
</xsl:stylesheet>
<group>
<section id="unique_1_Connect_42_PF.AlPF">
<msgph id="doc" xml:lang="en_US">It has been a external net failure. The pumps are blocked.</msgph>
<msgph id="cstext" xml:lang="en_US">Mains error</msgph>
<msgph id="localtext" xml:lang="en_US">Mains error</msgph>
</section>
<section id="unique_1_Connect_42_PersIntr.Personnel.AlPersonnelActive">
<msgph id="doc" xml:lang="en_US">Personal alarm warning time has run out without reset. Personnel in danger !</msgph>
<msgph id="cstext" xml:lang="en_US">Personal alarm</msgph>
<msgph id="localtext" xml:lang="en_US">Pers. alarm</msgph>
</section>
<section id="unique_2_Connect_42_PF.AlPF">
<msgph id="doc" xml:lang="es_ES">Ha habido un fallo de red externa. Las bombas están bloquedas.</msgph>
<msgph id="cstext" xml:lang="es_ES">Fallo energía de entrada</msgph>
<msgph id="localtext" xml:lang="es_ES">Fallo energía</msgph>
</section>
<section id="unique_2_Connect_42_PersIntr.Personnel.AlPersonnelActive">
<msgph id="doc" xml:lang="es_ES">Tiempo de espera de la alarma de personal ha finalizado sin reseteo. ¡Personal en peligro!</msgph>
<msgph id="cstext" xml:lang="es_ES">Alarma personal</msgph>
<msgph id="localtext" xml:lang="es_ES">Alarma personal</msgph>
</section>
</group>
<Rsc Id="PF.AlPF">
<Documentation en_US="It has been a external net failure. The pumps are blocked." es_ES="Ha habido un fallo de red externa. Las bombas están bloquedas."/>
<CSText en_US="Mains error" es_ES="Fallo energía de entrada"/>
<LocalText en_US="Mains error" es_ES="Fallo energía"/>
</Rsc>
<Rsc Id="PersIntr.Personnel.AlPersonnelActive">
<Documentation en_US="Personal alarm warning time has run out without reset. Personnel in danger !" es_ES="Tiempo de espera de la alarma de personal ha finalizado sin reseteo. ¡Personal en peligro!"/>
<CSText en_US="Personal alarm" es_ES="Alarma personal"/>
<LocalText en_US="Pers. alarm" es_ES="Alarma personal"/>
</Rsc>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vNewNames" select=
"'Documentation', 'CSText', 'LocalText'"/>
<xsl:template match="/*">
<xsl:for-each-group select="section"
group-by="substring-after(@id, '_42_')">
<xsl:variable name="vId" select=
"substring-after(@id, '42_')"/>
<Rsc Id="{$vId}">
<xsl:for-each-group select="current-group()/*"
group-by="@id">
<xsl:element name=
"{$vNewNames[starts-with(lower-case(.),current()/@id)]}">
<xsl:for-each select="current-group()">
<xsl:attribute name="{@xml:lang}" select="."/>
</xsl:for-each>
</xsl:element>
</xsl:for-each-group>
</Rsc>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
此代码使用了一些非常强大和最自然的XSLT 2.0功能,例如
,当前组()
,序列,的选择属性。结果是代码缩短了近两倍,可读性和可维护性大大提高。前缀模式是否像unique\u35; uconnect\u42
一样被修复?好问题,+1。有关使用Muenchian方法进行分组的完整解决方案,请参阅我的答案。前缀“pattern”是否像unique\u35;\u Connect\u 42\uuuu
一样固定?好问题,+1。请参阅我的答案,了解使用Muenchian方法进行分组的完整解决方案。哎哟,好的。忘了提我认为很明显的…我是一个新手,正在挣扎。哎哟,好吧。忘了提我认为很明显的…我是一个新手,正在挣扎。谢谢你,耶利米。我没有想过使用枚举来过滤掉我不需要的字符。你好,阿桑克斯,耶利米。我没有想过使用枚举来过滤掉我不需要的字符。您好,我有点惊讶,当海报上没有说他们必须使用XSLT1.0时,您竟然为分组问题提供了XSLT1.0解决方案。2.0中的解决方案会更容易理解,特别是对于一个不熟悉这门语言的人来说。@Michael Kay:我理解你的感受——两年前我也有同样的感受。我们必须接受人们不知道也不使用XSLT2.0的现实。这会影响新来者接触和学习XSLT2.0的速度,因为很少有人可以指导他们学习XSLT2.0,而且人们普遍认为XSLT2.0“更复杂”。我同意这是不幸的,但XSLT 1.0是99%(参见XSLT、XPath、XSLT-2.0、XPath-2.0的问题数量)这些人想要并请求帮助的东西:(.有什么改进的建议吗?@Michael Kay:添加了XSLT 2.0解决方案。我有点惊讶,当海报上没有说他们必须使用XSLT 1.0时,你竟然为分组问题提供了XSLT 1.0解决方案。2.0中的解决方案会更容易理解,特别是对于不熟悉该语言的人。@Micha艾尔凯:我了解你的费用