如何通过XSLT / XPATH选择特定值并将该值用于另一个标记?

时间:2016-09-08 12:22:33

标签: xslt xpath

我是XSLT的初学者,我想请求一些帮助。 需要使用XSLT 1.0 - 这里的任务:

这是我的简化输入xml:

<?xml version="1.0" encoding="UTF-8"?>
<FILE>
    <Partner>
        <NR>10</NR>
        <SR>
            <VK>100</VK>
            <PF>
                <TYPE>WE</TYPE>
                <NR>2345</NR>
            </PF>
            <PF>
                <TYPE>RE</TYPE>
                <NR>666</NR>
            </PF>
            <PF>
                <TYPE>RG</TYPE>
                <NR>999</NR>
            </PF>
            <RESULT></RESULT>
            ...
        </SR>
        <SR>
            <VK>200</VK>
            <PF>
                <TYPE>WE</TYPE>
                <NR>97564</NR>
            </PF>
            <RESULT></RESULT>
        </SR>
    </Partner>
    <Partner>
        <NR>20</NR>
        <SR>...</SR>
    </Partner>
</FILE>

目标输出必须如下所示: (如果存在type =“RG”的<PF>节点,则标记RESULT必须包含值,否则为空)

<?xml version="1.0" encoding="UTF-8"?>
<FILE>
    <Partner>
        <NR>10</NR>
        <SR>
            <VK>100</VK>
            <PF>
                <TYPE>WE</TYPE>
                <NR>2345</NR>
            </PF>
            <PF>
                <TYPE>RE</TYPE>
                <NR>666</NR>
            </PF>
            <PF>
                <TYPE>RG</TYPE>
                <NR>999</NR>
            </PF>
            <RESULT>999</RESULT>
            ...
        </SR>
        <SR>
            <VK>200</VK>
            <PF>
                <TYPE>WE</TYPE>
                <NR>97564</NR>
            </PF>
            <RESULT></RESULT>
        </SR>
   </Partner>
   <Partner>
       <NR>20</NR>
       <SR>...</SR>
   </Partner>
</FILE>

注意:
我在这里更新已经存在的工作和生产的xslt,所以我不能在这里改变一些主要的东西 这是相关编码的片段:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

    <xsl:template match="FILE">
        <FILE>
        <xsl:for-each select="./Partner">
            <Partner>
             ...

            <xsl:for-each select="./Partner/SR">
                ...

                <xsl:for-each select="./PF">
                    ...
                    <xsl:if test="(./PF/TYPE =RG)">
                        <RESULT><xsl:value-of select="./PF/NR"/></RESULT>
                    </xsl:if>     
                </xsl:for-each>


            </xsl:for-each>

            </Partner>
        </xsl:for-each>
        </FILE>
    </xsl:template>
</xsl:stylesheet>  

type = RG的测试成功,但它总是从WE类型的第一个数字2345复制。

如何从RG类型访问和复制特定值(999)?
PF条目的顺序和数量不固定。

1 个答案:

答案 0 :(得分:0)

您确定type = RG的测试是否成功?目前你这样做

 <xsl:if test="(./PF/TYPE =RG)">

但这是在<xsl:for-each select="PF">的上下文中,这意味着你的if语句正在寻找一个PF元素,它是当前PF元素的子元素(因此不会发现任何内容) 。另外,如果还要查找名为RG的元素来测试相等性,而不是文字。我认为应该是这样。

<xsl:if test="TYPE = 'RG'">

至于xsl:value-of,因为您已经定位在&#34; RG&#34;元素,表达式可以简化为NR。所以你的xsl:if就这样了:

<xsl:if test="TYPE = 'RG'">
    <RESULT><xsl:value-of select="NR"/></RESULT>
</xsl:if>     

话虽如此,看起来您的XSLT可以从使用XSLT identity template中受益,特别是如果您只是更改RESULT元素。

尝试使用此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="SR/RESULT">
        <xsl:copy>
            <xsl:value-of select="../PF[TYPE='RG']/NR" />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>