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

最初にキーを使用して、すべての一意のアイテム セットを識別します。識別されたグループごとに、a1 と b1 をコピーする「mode=group」テンプレートを実行し、他の 3 つの要素を子ノードにコピーする item-template を呼び出します。

于 2012-09-03T13:02:26.307 に答える
0

これはグループ化の問題であり、 を使用して簡単に解決できますxsl:for-each-group

ただし、グループ化基準があなたの例から正確に理解できていないため、正確なコードを提供することはできません.

于 2012-09-03T10:24:26.187 に答える