[英]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.