[英]Applying sequential numbering as attribute values of child nodes in one parent node, and then applying these in a different order in a sibling node
早上好,我有以下(双语)XML代码段:
<?xml version="1.0" encoding="UTF-8"?>
<tmx version="1.4">
<body>
<tu>
<prop type="x-Context">-2050338055591740051, -2050338055591740051</prop>
<prop type="x-Origin">TM</prop>
<prop type="x-ConfirmationLevel">Translated</prop>
<tuv>
<seg>
<ele>The text </ele>
<ele>
<ph x="0" type="QIAsymphony"/>
</ele>
<ele> goes </ele>
<ele>
<ph x="0" type="470"/>
</ele>
<ele> here </ele>
<ele>
<ph x="0" type="471"/>
</ele>
<ele>.</ele>
</seg>
</tuv>
<tuv>
<seg>
<ele>El texto </ele>
<ele>
<ph x="0" type="QIAsymphony"/>
</ele>
<ele> se mete </ele>
<ele>
<ph x="0" type="471"/>
</ele>
<ele> aquí </ele>
<ele>
<ph x="0" type="470"/>
</ele>
<ele>.</ele>
</seg>
</tuv>
</tu>
</body>
</tmx>
我想首先对第一个tuv / seg节点中ph元素的x属性值进行编号,从1到3(在这种情况下)。
但是,我得到的结果是这样的:
<tuv>
<seg>
<ele>The text </ele>
<ele>
<ph x="2" type="QIAsymphony"/>
</ele>
<ele> goes </ele>
<ele>
<ph x="4" type="470"/>
</ele>
<ele> here </ele>
<ele>
<ph x="6" type="471"/>
</ele>
<ele>.</ele>
</seg>
</tuv>
这基于以下XSLT样式表:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="tmx">
<tmx><xsl:attribute name="version"><xsl:value-of select="./@version"/></xsl:attribute>
<xsl:apply-templates/>
</tmx>
</xsl:template>
<xsl:template match="body">
<body>
<xsl:apply-templates/>
</body>
</xsl:template>
<xsl:template match="tuv">
<tuv>
<xsl:apply-templates/>
</tuv>
</xsl:template>
<xsl:template match="prop">
<prop><xsl:attribute name="type"><xsl:value-of select="./@type"/></xsl:attribute>
<xsl:apply-templates/>
</prop>
</xsl:template>
<xsl:template match="tu">
<tu>
<xsl:apply-templates/>
</tu>
</xsl:template>
<xsl:template match="tuv[1]/seg">
<seg>
<xsl:for-each select="ele">
<xsl:choose>
<xsl:when test="child::ph">
<ele><ph><xsl:attribute name="x">
<xsl:number/>
</xsl:attribute>
<xsl:attribute name="type">
<xsl:value-of select="ph/@type"/>
</xsl:attribute>
</ph></ele>
</xsl:when>
</xsl:choose>
<xsl:choose>
<xsl:when test="child::text()">
<xsl:copy-of select="."/>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</seg>
</xsl:template>
</xsl:stylesheet>
换句话说,我需要以下结果:
<tuv>
<seg>
<ele>The text </ele>
<ele>
<ph x="1" type="QIAsymphony"/>
</ele>
<ele> goes </ele>
<ele>
<ph x="2" type="470"/>
</ele>
<ele> here </ele>
<ele>
<ph x="3" type="471"/>
</ele>
<ele>.</ele>
</seg>
</tuv>
最后,基于第一个tuv / seg节点中的type属性值,我需要将相应的x值应用于第二个tuv / seg节点中的x属性(在这种情况下,其顺序将有所不同):
<tuv>
<seg>
<ele>El texto </ele>
<ele>
<ph x="1" type="QIAsymphony"/>
</ele>
<ele> se mete </ele>
<ele>
<ph x="3" type="471"/>
</ele>
<ele> aquí </ele>
<ele>
<ph x="2" type="470"/>
</ele>
<ele>.</ele>
</seg>
</tuv>
任何帮助将不胜感激。
要回答最直接的问题,得到数字2、4、6的原因是因为使用xsl:number
命令的方式
<xsl:attribute name="x">
<xsl:number/>
</xsl:attribute>
此时,您位于ele
元素上,因此当您只想计数带有子ph
元素的ele
元素时,将对所有ele
元素进行计数。 因此,您需要这样做
<xsl:attribute name="x">
<xsl:number count="ele[ph]"/>
</xsl:attribute>
但是,在回答有关为第二个tuv
元素编号的下一个问题之前,您需要了解XSLT身份转换。 您不必为每个要复制的节点编写显式模板,而只需一个模板就可以覆盖所有希望更改而无需修改的节点。 因此,您可以这样编写当前的样式表...
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="tuv[1]/seg/ele[ph]">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<ph type="{ph/@type}">
<xsl:attribute name="x">
<xsl:number count="ele[ph]"/>
</xsl:attribute>
</ph>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
但是要重新编号第二个tuv
元素,请考虑使用键在第一个tuv
元素中查找ele
元素
<xsl:key name="ph" match="tuv[1]/seg/ele/ph" use="@type" />
然后,要进行编号,您必须计算每个元素的先前同级数目
<xsl:attribute name="x">
<xsl:value-of select="count(key('ph', ../@type)/../preceding-sibling::ele[ph]) + 1" />
</xsl:attribute>
这将在两个tuv
元素中均起作用。
试试这个XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" />
<xsl:key name="ph" match="tuv[1]/seg/ele/ph" use="@type" />
<xsl:strip-space elements="*" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="tuv/seg/ele/ph/@x">
<xsl:attribute name="x">
<xsl:value-of select="count(key('ph', ../@type)/../preceding-sibling::ele[ph]) + 1" />
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.