このxmlを変換したいと思います:
<Root>
<Result>
<Message>
<Header>
<!-- Hundreds of child nodes -->
</Header>
<Body>
<Node1>
<!-- Hundreds of child nodes -->
<Node2>
<!-- Hundreds of child nodes -->
<Node3>
<!-- Hundreds of child nodes -->
<NodeX>value 1 to be changed</NodeX>
<!-- Hundreds of child nodes -->
<Node4>
<!-- Hundreds of child nodes -->
<NodeY>value 2 to be changed</NodeY>
</Node4>
</Node3>
</Node2>
</Node1>
</Body>
<RealValuesRoot>
<!-- These two nodes -->
<Value ID="1">this value must replace the value of Node X</Value>
<Value ID="2">this value must replace the value of Node Y</Value>
</RealValuesRoot>
</Message>
</Result>
<!-- Hundreds to thousands of similar MessageRoot nodes -->
</Root>
このxmlに:
<Root>
<Result>
<Message>
<Header>
<!-- Hundreds of child nodes -->
</Header>
<Body>
<Node1>
<!-- Hundreds of child nodes -->
<Node2>
<!-- Hundreds of child nodes -->
<Node3>
<!-- Hundreds of child nodes -->
<NodeX>this value must replace the value of Node X</NodeX>
<!-- Hundreds of child nodes -->
<Node4>
<!-- Hundreds of child nodes -->
<NodeY>this value must replace the value of Node Y</NodeY>
</Node4>
</Node3>
</Node2>
</Node1>
</Body>
</Message>
</Result>
<!-- Hundreds to thousands of similar MessageRoot nodes -->
</Root>
出力は、次の変更を除いて入力とほぼ同じです。
- X および Y ノードの値は、/RealValuesRoot/Value ノードの値に置き換える必要があります。
- /RealValuesRoot ノードを出力から削除する必要があります。
- xml の残りの部分は、出力で同じままにする必要があります。
「値」ノードには、メッセージの本文で一意の xpath を表す一意の ID があります。たとえば、ID 1 は xpath /Message/Body/Node1/Node2/Node3/NodeX を参照します。
Microsoft の xslt バージョン 1.0 を使用する必要があります!!
私はすでに正常に動作し、必要なすべてを実行する xslt を持っていますが、パフォーマンスには満足していません!
私のxsltは次のように機能します:
1:xpath1_2:xpath2_ … _N:xpathN のような、キーと値のペアのように機能するグローバル文字列変数を作成しました。この変数は、「値」ノードの ID を、置き換える必要があるメッセージ本文のノードに関連付けます。
xslt は、入力 xml をルート ノードから再帰的に反復します。
現在のノードの xpath を計算し、次のいずれかを実行します。
- 現在の xpath がグローバル リスト内の xpath の 1 つと完全に一致する場合、その値を対応する「値」ノードの値に置き換えて、反復を続けます。
- 現在の xpath が "RealValuesRoot" ノードを参照している場合は、そのノードを省略し (出力にコピーしないでください)、再帰的に反復を続けます。
- 現在の xpath がグローバル ID-xpath 文字列に存在しない場合は、完全なノードを出力にコピーし、反復を続行します。(これは、たとえば、交換が必要なノードを決して含まない /Message/Header ノードで発生します)
- 現在の xpath がグローバル リスト内の xpath の 1 つと部分的に一致する場合は、上記の 3 つのケースのいずれかに到達するまで単純に再帰的に繰り返します。
前述のとおり、私の xslt は正常に動作しますが、パフォーマンスを可能な限り改善したいと考えています。まったく新しい xslt ロジックを提案してください。あなたのアイデアや提案を歓迎します!