简体   繁体   English

将顺序编号应用为一个父节点中的子节点的属性值,然后在同级节点中以不同顺序应用它们

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

Good morning, I have the following (bilingual) XML snippet: 早上好,我有以下(双语)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>

I would like to first of all number the x attribute values of the ph elements in the first tuv/seg node, from 1 to 3 (in this case). 我想首先对第一个tuv / seg节点中ph元素的x属性值进行编号,从1到3(在这种情况下)。

However, the result I am getting is this: 但是,我得到的结果是这样的:

<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>

This is based on the following XSLT Stylesheet: 这基于以下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>

In order words, I need the following result: 换句话说,我需要以下结果:

  <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>

Finally, based on the type attribute values in the first tuv/seg node, I need to apply the corresponding x values to the x attributes in the second tuv/seg node (which in this case will be in a different order): 最后,基于第一个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>

Any assistance would be greatly appreciated. 任何帮助将不胜感激。

To answer your most immediate question, the reason you are getting the numbers 2, 4, 6 is because of how you use the xsl:number command 要回答最直接的问题,得到数字2、4、6的原因是因为使用xsl:number命令的方式

<xsl:attribute name="x">
   <xsl:number/>
</xsl:attribute>

You are positioned on an ele element at this point, so will be counting all ele elements, when it looks like you only want to count ones with child ph elements. 此时,您位于ele元素上,因此当您只想计数带有子ph元素的ele元素时,将对所有ele元素进行计数。 Therefore you need to do this 因此,您需要这样做

<xsl:attribute name="x">
   <xsl:number count="ele[ph]"/>
</xsl:attribute>

However, before answering your next issue about numbering the second tuv element, you need to learn about the XSLT identity transform. 但是,在回答有关为第二个tuv元素编号的下一个问题之前,您需要了解XSLT身份转换。 Rather than write explicit templates for every single node you wish to copy, you just have a single one to cover all those you wish to change without amending. 您不必为每个要复制的节点编写显式模板,而只需一个模板就可以覆盖所有希望更改而无需修改的节点。 So you could write your current stylesheet as just this... 因此,您可以这样编写当前的样式表...

<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>

But to re-number the second tuv element, consider using a key to look up the ele elements in the first tuv element 但是要重新编号第二个tuv元素,请考虑使用键在第一个tuv元素中查找ele元素

<xsl:key name="ph" match="tuv[1]/seg/ele/ph" use="@type" />

Then, to do the numbering, you would have to count the number of preceding siblings for each element 然后,要进行编号,您必须计算每个元素的先前同级数目

    <xsl:attribute name="x">
        <xsl:value-of select="count(key('ph', ../@type)/../preceding-sibling::ele[ph]) + 1" />
    </xsl:attribute>

This would work in both tuv elements. 这将在两个tuv元素中均起作用。

Try this XSLT 试试这个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.

相关问题 在XSLT中以与父节点不同的顺序到达子节点 - Reaching the child node in different order from parent nodes in XSLT 在基于兄弟后代节点的节点的子节点属性值中添加新的子节点 - add new child nodes in sibling descendant node based node's child node attribute value XPath 2 / XSLT:查找具有匹配的子节点值的集合的兄弟节点 - XPath 2 / XSLT : Find sibling nodes of a set with matching values of child node Perl:在xml父节点中迭代一个子节点的特定值,并比较该父节点下其他子节点的值 - Perl: Iterating through an xml parent node for a particular value of one child node and comparing values for other child nodes under that parent node 使用php提取父节点的属性值以及子节点的相应文本值 - Extract attribute value of parent node using php along with corresponding text values of child nodes XSLT:将模板与来自祖先的兄弟节点的数据一起应用 - XSLT: Applying a template with data from an ancestor's sibling node 将子节点复制到其父级的同级子节点中 - Copying a Child Node into its Parent's Sibling's Child Node 将选择节点的兄弟节点移动到新的父节点 - Move certain nodes that are sibling of select node into a new parent node 如何将子节点及其值移动到父节点 - How move Child Nodes along with values to grand parent node 通过插入父节点来更改子节点值 - Change Child Node Values by inserting parent nodes iterative
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM