3

変更が必要な XML ファイルがあります。まず、group by を実行してから、いくつかのノードを除外する必要があります。

<cars>
    <car>
        <make>Toyota</make>
        <model>Camry</model>
        <color>White</color>
        <price>123</price>
    </car>
    <car>
        <make>Honda</make>
        <model>Accord</model>
        <color>White</color>
        <price>423</price>
    </car>
</cars>

変換を行う私のコードは次のとおりです。

<root>
    {
    for $color in distinct-values(doc('cars.xml')//cars/car/color)
    let $car := doc('cars.xml')//cars/car
    return  <appearance color="{$color}">
            { $car[color eq $color ] }
            </appearance>
    }
</root>

私は得る:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <appearance color="White">
        <car>
            <make>Toyota</make>
            <model>Camry</model>
            <color>White</color>
            <price>123</price>
        </car>
        <car>
            <make>Honda</make>
            <model>Accord</model>
            <color>White</color>
            <price>423</price>
        </car>
    </appearance>
</root>

これは、1 つの問題を除いて、私が必要とすることの 95% を行います。グループ化を維持しながら、最終的な XML からノード「color」と「price」を除外する必要があります。

returnステートメントで次のことを試みました: { $car[color eq $color ]/*[not(self::price)][not(self::color)] }

動作しますが、「車」要素を完全に排除します!! 何かアドバイス?

4

3 に答える 3

5

これを試して:

<root>
{
    let $cars-doc := doc('cars.xml')
    let $color := distinct-values($cars-doc//cars/car/color)
    return
        for $carcolor in $color
        return
            <appearance color="{$carcolor}">
            {
                for $car in $cars-doc//cars/car
                where $car/color = $carcolor
                return 
                    <car>
                    {$car/*[not(self::color or self::price)]}
                    </car>  
            }
            </appearance>
}
</root>  

お役に立てれば。

于 2012-04-21T06:19:51.100 に答える
1

私は黒い豚のソリューションが好きですが、次のコードの少しきれいなバージョンをお勧めします。次の方法でよりきれいにします。

  1. cars はルート要素であるため、 //cars を使用する必要はありません
  2. 最初の return ステートメントは不要です
  3. 車/車を繰り返し横断する必要はありません
  4. 変数名で単数形と複数形を使用して、単一項目とシーケンスを示します

    <root>
        {
        let $cars := doc('cars.xml')//car
        let $colors := distinct-values($cars/color)
        for $color in $colors
        return
            <appearance color="{$color}">
                {
                for $car in $cars[color = $color]
                return 
                    <car>
                        {$car/*[not(self::color or self::price)]}
                    </car>  
                }
            </appearance>
        }
    </root>
    
于 2012-04-21T22:03:34.927 に答える
0

XPath では、新しいノードを作成できないことに注意してください。入力ドキュメントに既に存在するノードを変更せずに返すか、カウントや合計などの値を計算できますが、新しいノード ツリーまたは変更されたノード ツリーが必要な場合は、XSLT または XQuery が必要です。

小さな変更を加えて出力が入力と同様になる場合は、多くの場合、XSLT ソリューションの方が XQuery ソリューションよりもはるかに単純です。

于 2012-04-21T16:56:05.277 に答える