对*几乎*唯一的 ID 进行分组
我正在努力将几乎相同的 id 分组。基本上我需要对 PF.A1PF 和 PersIntr.Personnel.AlPersonnelActive 部分的内容进行分组,并在获取我的 id 之前删除子字符串。我没有所有部分 ID 的列表。
请参阅下面的示例。
这是当前的 XML:
<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>
我真的很感激任何见解。预先感谢您的关注。
亲切的问候, 安妮
更新: 非常感谢,@Dimitre,@Michael。我非常感谢您对这一挑战的帮助。我在 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>
再次感谢! 安妮
I'm struggling with grouping ids that are almost the same. Basically I need to group the content of the PF.A1PF and PersIntr.Personnel.AlPersonnelActive sections and strip the substring before to get my id. I do not have a listing of all the section ids.
Please see below for examples.
Here's the current XML:
<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>
Here's what I need to output:
<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>
I really appreciate any insight. Thanks in advance for your attention.
Kind regards,
Anne
Update:
Thanks so much, @Dimitre, @Michael. I really appreciate your help with this challenge. I had a little trouble with the element resolving in this portion of the 2.0 solution:
<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>
Here's what finally worked:
<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>
Thanks again!
Anne
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
此转换:
应用于提供的 XML 文档时:
准确产生所需的正确结果:
说明:< a href="http://www.jeniitennison.com/xslt/grouping/muenchian.html" rel="nofollow">Muenchian 分组,其键定义为以下子字符串
id
属性。二. XSLT 2.0 解决方案:
此代码使用了一些非常强大且最自然的 XSLT 2.0 功能,例如
、current-group()
、序列、
的select
属性。结果是代码几乎缩短了一倍,并且更具可读性和可维护性。This transformation:
when applied on the provided XML document:
produces exactly the wanted, correct result:
Explanation: Muenchian grouping with key that is defined as a substring of the
id
attribute.II. XSLT 2.0 solution:
This code uses some very powerful and most natural XSLT 2.0 features, such as
<xsl:for-eac-group>
,current-group()
, sequences, theselect
attribute of<xsl:attribute>
. The result is almost twice shorter code that is much more readable and maintainable.我对 XSLT 了解不多,但似乎您应该能够使用 XSLT substring 函数 去除每个section[id] 的前22 个字符并返回重要部分。
I don't know a considerable amount about XSLT, but it seems like you should be able to use the XSLT substring function to strip out the first 22 characters of each section[id] and return the significant portion.
定义“几乎”。只有这样你才能想出一个合理的解决方案。您很可能会使用基本的 xslt 函数自行解决该问题。
Define "almost". Only then you'll be able to come up with a reasonable solution. Most likely you will then solve it yourself with basic xslt functions.