2016-06-24 15 views
0

は、私はすべてのsource/@id値を付け直すと、更新された値と一致するすべてtarget/@idを更新したい。このXMLXSLT:同じ@値とコンテキストノードと別のノードに属性値を付け直す

<?xml version="1.0"?> 
<root> 
    <lev1> 
     <source id="1"/> 
     <target id="1"/> 
    </lev1> 
    <lev1> 
     <source id="2"/> 
     <sometag/> 
     <lev2> 
      <sometag/> 
      <target id="2"/> 
      <target id="4"/> 
     </lev2> 
     <source id="4"/> 
     <sometag/> 
     <source id="5"/> 
     <lev2> 
      <target id="6"/> 
     </lev2> 
    </lev1> 
</root> 

を考えます。私はすべてのノードが元の位置を保持するようにしたいと思いますが、一致する箇所にはtarget/@idがないコメントを生成したいと思います。

このXSLTは私の出発点だった:

<?xml version='1.0'?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:key name="kTarget" match="target" use="@id"/> 


<xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 


<xsl:template match="source"> 
<xsl:variable name="newId"> 
    <xsl:number from="/" level="any"/> 
</xsl:variable> 
    <newsource> 
    <xsl:attribute name="id"><xsl:value-of select="$newId"/></xsl:attribute> 
    </newsource> 
    <xsl:call-template name="renumTarget"> 
     <xsl:with-param name="newId"><xsl:value-of select="$newId"/></xsl:with-param> 
    </xsl:call-template> 
</xsl:template> 

<xsl:template match="target"/> 

<xsl:template name="renumTarget"> 
<xsl:param name="newId"/> 
    <xsl:comment>new id : <xsl:value-of select="$newId"/> old id : <xsl:value-of select="@id"/></xsl:comment> 
    <xsl:element name="newtarget"> 
     <xsl:attribute name="id"><xsl:value-of select="$newId"/></xsl:attribute> 
     <xsl:apply-templates/> 
    </xsl:element> 
</xsl:template> 




</xsl:stylesheet> 

は、私は新しいノードを配置することができず、古い値と新しい値を選ぶことができています...しかし。これは、一致する@idが存在しない領域も識別しません。

xsltでoldVal-> newVal種類の関数を持つマップを作成する方法はありますか?

ありがとうございました!

+0

どのように結果は見えるだろうか?空の場所に新しい価値を入れるべきですか? – zx485

+0

id = 3のターゲットがあり、対応するソースがないとします。そして、ソースの番号を付け直すと、id = 3のソースが生成されたとします。old id = 3のターゲットの新しいIDはどうなりますか? –

答えて

1

私はあなたがsourceせずに対応するtargetまたはtargetせずに、それぞれsourcenewsourceにコメントを生成するかどうかわからない、以下の両方を生成します。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

    <xsl:key name="kTarget" match="target" use="@id"/> 
    <xsl:key name="kSource" match="source" use="@id"/> 

    <xsl:template match="node() | @*" name="identity"> 
     <xsl:copy> 
      <xsl:apply-templates select="node() | @*"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="source" mode="number"> 
     <xsl:number level="any"/> 
    </xsl:template> 

    <xsl:template match="source"> 
     <xsl:variable name="newId"> 
      <xsl:apply-templates select="." mode="number"/> 
     </xsl:variable> 
     <newsource id="{$newId}"/> 
     <xsl:if test="not(key('kTarget', @id))"> 
      <xsl:comment> 
        <xsl:value-of select="concat('No target for old id ', @id, ' replaced by ', $newId)"/> 
       </xsl:comment> 
     </xsl:if> 
    </xsl:template> 

    <xsl:template match="target[key('kSource', @id)]"> 
     <xsl:variable name="changed-id"> 
      <xsl:apply-templates select="key('kSource', @id)" mode="number"/> 
     </xsl:variable> 
     <target id="{$changed-id}"/> 
    </xsl:template> 

    <xsl:template match="target[not(key('kSource', @id))]"> 
     <xsl:call-template name="identity"/> 
     <xsl:comment> 
      <xsl:value-of select="concat('No source for target with id ', @id)"/> 
     </xsl:comment> 
    </xsl:template> 

</xsl:stylesheet> 

ご入力サンプルに適用すると、私は出力を得る

<root> 
    <lev1> 
     <newsource id="1"/> 
     <target id="1"/> 
    </lev1> 
    <lev1> 
     <newsource id="2"/> 
     <sometag/> 
     <lev2> 
      <sometag/> 
      <target id="2"/> 
      <target id="3"/> 
     </lev2> 
     <newsource id="3"/> 
     <sometag/> 
     <newsource id="4"/><!--No target for old id 5 replaced by 4--> 
     <lev2> 
      <target id="6"/><!--No source for target with id 6--> 
     </lev2> 
    </lev1> 
</root> 
+0

これは、誤って孤立したターゲットを任意のソースに割り当てる可能性があります。 –

関連する問題