2017-04-12 14 views
2

ある種の入力リストに応じて、いくつかの属性を変更するための非常にフラットなXMLファイルがあります。私が解決できないトリッキーな部分は、1つのノードだけでなく、見つかったノードを参照する兄弟ノードでも属性を変更したいということです。XSLT兄弟属性を変更するために属性を入力として使用する

私は、次のXMLファイルを持っている:

<?xml version="1.0" encoding="utf-8"?> 
<Root> 
    <SubItem id="id21" cls="classA" name="FirstSub" master="#id30"/> 
    <SubItem id="id22" cls="classA" name="SecondSub" master="#id31"/> 
    <SubItem id="id23" cls="classA" name="ThirdSub" master="#id32"/> 
    <SubItem id="id24" cls="classA" name="FourthSub" master="#id33"/> 
    <SubItem id="id25" cls="classA" name="FifthSub" master="#id34"/> 
    <Item id="id30" cls="classA" name="First"/> 
    <Item id="id31" cls="classA" name="Second"/> 
    <Item id="id32" cls="classA" name="Third"/> 
    <Item id="id33" cls="classA" name="Fourth"/> 
    <Item id="id34" cls="classA" name="Fifth" /> 
</Root> 

そして、私はcls属性値を変更したい要素のname値リスト次の追加の入力ファイル:

<input> 
    <ToClassB> 
     <Name>Second</Name> 
     <Name>Third</Name> 
    </ToClassB> 
</input> 

して、次のようにXSLTは、nameの値が追加入力リストの値と一致する要素に対してうまく機能します。

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:plm="http://www.plmxml.org/Schemas/PLMXMLSchema" exclude-result-prefixes="xs" 
    version="2.0"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="no"/> 

    <xsl:variable name="inputs" select="document('file:/C:/Temp//demoInput.xml')"/> 

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

    <xsl:template match="/Root/Item/@name[. = $inputs/input/ToClassB/Name/text()]"> 
     <xsl:variable name="elemName" select="../@id"/> 
     <xsl:copy> 
      <xsl:copy-of select="../@name"/> 
     </xsl:copy> 
     <xsl:attribute name="cls"> 
      <xsl:value-of select="'classB'" /> 
     </xsl:attribute> 

    </xsl:template> 
</xsl:stylesheet> 

私の予想結果:"Second"または"Third"name値に一致しており、そのcls属性値がClassBに変更されているだけでなく、関連SubItem要素についてcls属性値を持つ

<?xml version="1.0" encoding="UTF-8"?> 
<Root> 
    <SubItem id="id21" cls="classA" name="FirstSub" master="#id30"/> 
    <SubItem id="id22" cls="ClassB" name="SecondSub" master="#id31"/> 
    <SubItem id="id23" cls="ClassB" name="ThirdSub" master="#id32"/> 
    <SubItem id="id24" cls="classA" name="FourthSub" master="#id33"/> 
    <SubItem id="id25" cls="classA" name="FifthSub" master="#id34"/> 
    <Item id="id30" cls="classA" name="First"/> 
    <Item id="id31" cls="ClassB" name="Second"/> 
    <Item id="id32" cls="ClassB" name="Third"/> 
    <Item id="id33" cls="classA" name="Fourth"/> 
    <Item id="id34" cls="classA" name="Fifth"/> 
</Root> 

項目タグ(マスター属性参照ID属性はItemです)。

これはXSLTですべて可能ですか、何かプログラミングをする必要がありますか?

+0

あなたは '同じに' 'に関連付けられているすべての' に依存することができますドキュメント、 'SubItem/@ master'と' Item/@ id'を介して?また、要素の順序を保持する必要がありますか? –

+0

私の質問のポイントは、スタイルシートを再構成して、テンプレート ' 'のテンプレートが' '子に直接テンプレートを適用するのではなく、そのテンプレートに ' ''にテンプレートを適用します。 'cls'属性の変換方法を正しく指示するのに十分なコンテキストがあります。 –

+1

XSLT _is_プログラミング;-) –

答えて

0

SubItemからItemを参照するxsl:キーを作成できます。 1つのテンプレートを使用して、idまたはmasterのいずれかの属性を使用してキーにアクセスできます。

例...

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:key name="itemsByID" match="Item" use="@id"/> 

    <xsl:variable name="inputs" 
    select="document('demoInput.xml')/input/ToClassB/Name"/> 

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

    <xsl:template match="Item|SubItem"> 
    <xsl:variable name="refid" 
     select="if (@master) then substring-after(@master,'#') else @id"/> 
    <xsl:copy> 
     <xsl:apply-templates select="@*"/> 
     <xsl:attribute name="cls" 
     select="if (key('itemsByID',$refid)/@name = $inputs) 
     then 'ClassB' else @cls"/> 
     <xsl:apply-templates select="node()"/> 
    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

出力

<Root> 
    <SubItem id="id21" cls="classA" name="FirstSub" master="#id30"/> 
    <SubItem id="id22" cls="ClassB" name="SecondSub" master="#id31"/> 
    <SubItem id="id23" cls="ClassB" name="ThirdSub" master="#id32"/> 
    <SubItem id="id24" cls="classA" name="FourthSub" master="#id33"/> 
    <SubItem id="id25" cls="classA" name="FifthSub" master="#id34"/> 
    <Item id="id30" cls="classA" name="First"/> 
    <Item id="id31" cls="ClassB" name="Second"/> 
    <Item id="id32" cls="ClassB" name="Third"/> 
    <Item id="id33" cls="classA" name="Fourth"/> 
    <Item id="id34" cls="classA" name="Fifth"/> 
</Root> 
関連する問題