XSLT父子遍历无法正常工作



这是真实的场景,只有我更改了数据。我有下面的父子关系xml。我正在尝试使用XSLT转换下面的xml。我能够转换父数据,但不能给出子节点的条件,比如如果子引用在任何时候发生变化,它应该分离样本,否则它应该由子节点分离。

输入文档

<Samples>
    <Sample>
        <a1>a1name</a1>
        <b1>b1desc</b1>
        <c1ref>101</c1ref>
        <childref>101</childref>
        <eno>test</eno>
        <ename>somename</ename>
    </Sample>
    <Sample>
        <a1>a1name</a1>
        <b1>b1desc</b1>
        <c1ref>101</c1ref>
        <childref>101</childref>
        <eno>test123</eno>
        <ename>someothername</ename>
    </Sample>
    <Sample>
        <a1>a1name1</a1>
        <b1>b1desc1</b1>
        <c1ref>102</c1ref>
        <childref>102</childref>
        <eno>test1234</eno>
        <ename>someothername1</ename>
    </Sample>
    <Sample>
        <a1>a1name</a1>
        <b1>b1desc</b1>
        <c1ref>101</c1ref>
        <childref>101</childref>
        <eno>test</eno>
        <ename>somename</ename>
    </Sample>
    <Sample>
        <a1>a1name1</a1>
        <b1>b1desc1</b1>
        <c1ref>103</c1ref>
        <childref>103</childref>
        <eno>test1234</eno>
        <ename>someothername1</ename>
    </Sample>
</Samples>

OP没有解释。可能是预期的输出文档

<Samples>
    <Sample>
        <a1>a1name</a1>
        <b1>b1desc</b1>
        <c1ref>101</c1ref>
        <childs>
            <childref>101</childref>
            <eno>test</eno>
            <ename>somename</ename>
        </childs>
        <childs>
            <childref>101</childref>
            <eno>test123</eno>
            <ename>someothername</ename>
        </childs>
    </Sample>
    <Sample>
        <a1>a1name1</a1>
        <b1>b1desc1</b1>
        <c1ref>102</c1ref>
        <childs>
            <childref>102</childref>
            <eno>test1234</eno>
            <ename>someothername1</ename>
        </childs>
    </Sample>
</Samples>

下面的XSLT工作,但它再次重复childref 101。

    <?xml version="1.0" encoding="UTF-8"?> 
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0">       
    <xsl:output indent="yes" method="xml"/>
    <xsl:template match="Samples">     
    <xsl:copy>         
    <!-- select the first Sample -->
    <xsl:apply-templates select="Sample[1]"/>
    </xsl:copy> </xsl:template>  
    <xsl:template match="Sample">
    <!-- the a1 attribute in Sample will act as the identifier 
    (check if it is the same      element) -->     
    <xsl:variable name="identifier" select="a1"/>
     <xsl:copy>         
      <xsl:apply-templates select="a1"/> 
        <xsl:apply-templates select="b1"/>
         <xsl:apply-templates select="c1ref"/>
         <xsl:element name="childs">
             <xsl:apply-templates select="childref"/>
             <xsl:apply-templates select="eno"/>
             <xsl:apply-templates select="ename"/>
         </xsl:element>         
         <!-- get childs of Sample with same identifier -->
         <xsl:apply-templates 
         select="following-sibling::Sample[a1=$identifier]"
         mode="SameElement"/>     
</xsl:copy>     
<!-- select the nex Samples with different identifier -->
<xsl:apply-templates select="following-sibling::Sample[a1!=$identifier][1]"/>      </xsl:template>
<xsl:template match="Sample" mode="SameElement">
     <!-- here only output the child elements -->
     <xsl:element name="childs">
         <xsl:apply-templates select="childref"/>
         <xsl:apply-templates select="eno"/>
         <xsl:apply-templates select="ename"/>
     </xsl:element> </xsl:template>
<xsl:template match="*|@*|text()"> 
    <xsl:copy>
         <xsl:apply-templates/>
     </xsl:copy> 
</xsl:template> 
</xsl:stylesheet>      

如何编写将产生上述输出的xslt

老实说,我无法找出XSLT中的错误。因此,我使用分层分组(Jeni Tennison描述)提出了自己的版本。这是一个XSLT1.0解决方案。如果我使用这个输入XML:

<?xml version="1.0" encoding="UTF-8"?>
<Samples>
<Sample>
    <a1>a1name</a1>
    <b1>b1desc</b1>
    <c1ref>101</c1ref>
    <childref>101</childref>
    <eno>test</eno>
    <ename>somename</ename>
</Sample>
<Sample>
    <a1>a1name</a1>
    <b1>b1desc</b1>
    <c1ref>101</c1ref>
    <childref>101</childref>
    <eno>test123</eno>
    <ename>someothername</ename>
</Sample>
<Sample>
    <a1>a1name1</a1>
    <b1>b1desc1</b1>
    <c1ref>102</c1ref>
    <childref>102</childref>
    <eno>test1234</eno>
    <ename>someothername1</ename>
</Sample>
<Sample>
    <a1>a1name</a1>
    <b1>b1desc</b1>
    <c1ref>101</c1ref>
    <childref>101</childref>
    <eno>test</eno>
    <ename>somename</ename>
</Sample>
<Sample>
    <a1>a1name1</a1>
    <b1>b1desc1</b1>
    <c1ref>103</c1ref>
    <childref>103</childref>
    <eno>test1234</eno>
    <ename>someothername1</ename>
</Sample>
</Samples>

并应用此XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="keyByc1ref" match="Sample" use="c1ref"/>
<xsl:template match="Samples">
    <xsl:variable name="uniqueSet" select="Sample[generate-id()=generate-id(key('keyByc1ref',c1ref)[1])]"/>
    <Samples>
        <xsl:apply-templates select="$uniqueSet" mode="group"/>
    </Samples>
</xsl:template>
<xsl:template match="Sample" mode="group">
    <Sample>
        <xsl:copy-of select="a1"/>
        <xsl:copy-of select="b1"/>
        <xsl:apply-templates select="key('keyByc1ref',c1ref)" mode="item"/>
    </Sample>
</xsl:template>
<xsl:template match="Sample" mode="item">
    <childs>
        <xsl:copy-of select="childref"/>
        <xsl:copy-of select="eno"/>
        <xsl:copy-of select="ename"/>
    </childs>
</xsl:template>
</xsl:stylesheet>

我得到了这个XML输出。我认为它看起来不错,我不确定预期的输出:

<?xml version="1.0" encoding="UTF-8"?>
<Samples>
<Sample>
    <a1>a1name</a1>
    <b1>b1desc</b1>
    <childs>
        <childref>101</childref>
        <eno>test</eno>
        <ename>somename</ename>
    </childs>
    <childs>
        <childref>101</childref>
        <eno>test123</eno>
        <ename>someothername</ename>
    </childs>
    <childs>
        <childref>101</childref>
        <eno>test</eno>
        <ename>somename</ename>
    </childs>
</Sample>
<Sample>
    <a1>a1name1</a1>
    <b1>b1desc1</b1>
    <childs>
        <childref>102</childref>
        <eno>test1234</eno>
        <ename>someothername1</ename>
    </childs>
</Sample>
<Sample>
    <a1>a1name1</a1>
    <b1>b1desc1</b1>
    <childs>
        <childref>103</childref>
        <eno>test1234</eno>
        <ename>someothername1</ename>
    </childs>
</Sample>
</Samples>

使用开头的键可以识别所有唯一的项目集。对于每个识别的组;模式=组";复制a1和b1并调用将其他3个元素复制到子节点中的项模板的模板。

这是一个分组问题,可以使用xsl:for-each-group轻松解决。

然而,我还没有从你的例子中准确地计算出你的分组标准是什么,所以我不能给你精确的代码。

相关内容

  • 没有找到相关文章

最新更新