将匹配的2个不同子元素xml值放在xslt2.0的单行中

时间:2014-08-21 14:58:20

标签: xml xslt

我有以下输入xml,

<GSKProductHierarchy>
<GlobalBusinessIdentifier>ZGB001</GlobalBusinessIdentifier>
<Hierarchy>
    <Material>335165140779</Material>
    <Level1>02</Level1>
    <Level2>02AQ</Level2>
    <Level3>02AQ006</Level3>
    <Level4>02AQ006309</Level4>
    <Level5>02AQ006309</Level5>
    <Level6>02AQ006309</Level6>
    <Level7>02AQ006309</Level7>
    <Level8>02AQ006309</Level8>
</Hierarchy>
<Hierarchy>
    <Material>335165140780</Material>
    <Level1>02</Level1>
    <Level2>02AQ</Level2>
    <Level3>02AQ006</Level3>
    <Level4>02AQ006309</Level4>
    <Level5>02AQ006309</Level5>
    <Level6>02AQ006309</Level6>
    <Level7>02AQ006309</Level7>
    <Level8>02AQ006310</Level8>
</Hierarchy>
    <Texts>
    <ProductHierarchy>02AQ006310</ProductHierarchy>
    <Language>A</Language>
    <Description>CREAM</Description>
</Texts>
<Texts>
    <ProductHierarchy>02AQ006309</ProductHierarchy>
    <Language>B</Language>
    <Description>CREAM</Description>
</Texts>

根据要求,xsl应检查GSKProductHierarchy / Texts / ProductHierarchy元素中GSKProductHierarchy / Hierarchy / Level8的匹配值...并且其结果应如下所示。

335165140779|02|02AQ|02AQ006|02AQ006309|02AQ006309|02AQ006309|02AQ006309|02AQ006309|02AQ006309|A|CREAM|
335165140780|02|02AQ|02AQ006|02AQ006309|02AQ006309|02AQ006309|02AQ006309|02AQ006310|02AQ006310|B|CREAM|

现在我有以下xslt,

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" xmlns:set="http://exslt.org/sets" xmlns:str="http://exslt.org/strings" xmlns:java="http://xml.apache.org/xslt/java" xmlns:saxon="http://saxon.sf.net/" exclude-result-prefixes="exsl set str java saxon">
<xsl:output method="text" indent="yes"/>
<xsl:variable name="VarPipe" select="'|'"/>
<xsl:variable name="VarBreak" select="'&#xa;'"/>
<xsl:template match="/">
    <xsl:for-each select="GSKProductHierarchy/Hierarchy">
        <xsl:variable name="currentIndex" select="position()"/>
        <xsl:variable name="Level8" select="Level8"/>
        <xsl:variable name="ProductHierarchy" select="../Texts[$currentIndex]/ProductHierarchy"/>
        <xsl:if test="$Level8=$ProductHierarchy">
            <xsl:value-of select="Material"/>
            <xsl:value-of select="$VarPipe"/>
            <xsl:value-of select="Level1"/>
            <xsl:value-of select="$VarPipe"/>
            <xsl:value-of select="Level2"/>
            <xsl:value-of select="$VarPipe"/>
            <xsl:value-of select="Level3"/>
            <xsl:value-of select="$VarPipe"/>
            <xsl:value-of select="Level4"/>
            <xsl:value-of select="$VarPipe"/>
            <xsl:value-of select="Level5"/>
            <xsl:value-of select="$VarPipe"/>
            <xsl:value-of select="Level6"/>
            <xsl:value-of select="$VarPipe"/>
            <xsl:value-of select="Level7"/>
            <xsl:value-of select="$VarPipe"/>
            <xsl:value-of select="Level8"/>
            <xsl:value-of select="$VarPipe"/>
            <xsl:value-of select="../Texts[$currentIndex]/ProductHierarchy"/>
            <xsl:value-of select="$VarPipe"/>
            <xsl:value-of select="../Texts[$currentIndex]/Language"/>
            <xsl:value-of select="$VarPipe"/>
            <xsl:value-of select="../Texts[$currentIndex]/Description"/>
            <xsl:value-of select="$VarPipe"/>
            <xsl:if test="not(position() = last())">
                <xsl:value-of select="$VarBreak"/>
            </xsl:if>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          

任何人都可以建议我应该使用什么功能来获得所需的结果。

此致 吉瑞

1 个答案:

答案 0 :(得分:0)

您的XSLT当前未获得所需输出的原因是由于这些行

 <xsl:variable name="ProductHierarchy" select="../Texts[$currentIndex]/ProductHierarchy"/>
 <xsl:if test="$Level8=$ProductHierarchy">

代码假设Texts元素的顺序与Hierarchy节点的顺序相同。但第一个Hierarchy的Level8值为“02AQ006309”,但这与第二个Texts元素相对应。

如果您确实要查找Text个元素,而不是ProductHierarchy,那么请考虑使用密钥

<xsl:key name="Text" match="Texts" use="ProductHierarchy" />

要使用密钥,您只需执行此操作,例如:

<xsl:value-of select="key('Text', $Level8)/Language"/>

试试这个XSLT:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="yes"/>
<xsl:variable name="VarPipe" select="'|'"/>
<xsl:variable name="VarBreak" select="'&#xa;'"/>

<xsl:key name="Text" match="Texts" use="ProductHierarchy" />

<xsl:template match="/">
    <xsl:for-each select="GSKProductHierarchy/Hierarchy">
         <xsl:value-of select="Material"/>
         <xsl:value-of select="$VarPipe"/>
         <xsl:value-of select="Level1"/>
         <xsl:value-of select="$VarPipe"/>
         <xsl:value-of select="key('Text', Level8)/ProductHierarchy" />
         <xsl:value-of select="$VarPipe"/>
         <xsl:value-of select="key('Text', Level8)/Language"/>
         <xsl:value-of select="$VarPipe"/>
         <xsl:if test="not(position() = last())">
             <xsl:value-of select="$VarBreak"/>
         </xsl:if>
    </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

我没有在这里输出所有字段,只是为了让XSLT更加简单。实际上,如果您确实使用的是XSLT 2.0,则可以轻松简化XSLT并仍然输出所有字段。也试试这个XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="yes"/>

<xsl:variable name="VarPipe" select="'|'"/>
<xsl:variable name="VarBreak" select="'&#xa;'"/>

<xsl:key name="Text" match="Texts" use="ProductHierarchy" />

<xsl:template match="/">
    <xsl:for-each select="GSKProductHierarchy/Hierarchy">
         <xsl:value-of select="*" separator="{$VarPipe}" />
         <xsl:value-of select="key('Text', Level8)/*" separator="{$VarPipe}" />
         <xsl:if test="not(position() = last())">
             <xsl:value-of select="$VarBreak"/>
         </xsl:if>
    </xsl:for-each>
</xsl:template>
</xsl:stylesheet>