-2

这是真实的场景,只有我更改了数据。我有以下父子关系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?

4

2 回答 2

1

老实说,我无法弄清楚您的 XSLT 中的错误。所以我想出了我自己的版本,使用层次分组(由 Jeni Tennison 描述)。这是一个 XSLT 1.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>

使用开头的键,您可以识别所有独特的项目集。对于每个标识的组,您运行“mode=group”模板,该模板复制 a1 和 b1,并调用将其他 3 个元素复制到子节点的 item-template。

于 2012-09-03T13:02:26.307 回答
0

这是一个分组问题,可以使用xsl:for-each-group.

但是,我还没有设法从您的示例中准确计算出您的分组标准,因此我无法为您提供精确的代码。

于 2012-09-03T10:24:26.187 回答