我正在努力解决几乎相同的分组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>
再次感谢! 安
答案 0 :(得分:1)
此转化:
<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>
应用于提供的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>
</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>
解释:Muenchian grouping,其键定义为id
属性的子字符串。
<强> II。 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: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:for-eac-group>
,current-group()
,序列,select
<xsl:attribute>
属性}}。结果几乎是代码的两倍,更易读和可维护。
答案 1 :(得分:0)
我不太了解XSLT,但似乎你应该能够使用XSLT substring function来删除每个部分[id]的前22个字符并返回重要部分。
答案 2 :(得分:0)
定义“差不多”。只有这样,你才能找到合理的解决方案。您很可能会使用基本的xslt函数自行解决它。