2013-05-11 5 views
1

У меня есть XML:добавление атрибута, значение которого является значение атрибута чужого элемента

<graph> 
<node id="a" /> 
<node id="b" /> 
<node id="c" /> 
<node id="d" /> 

<link from="a" id="link1" to="b"/> 
<link from="b" id="link2" to="d"/> 
<link from="d" id="link3" to="c"/> 

</graph> 

я хочу, чтобы преобразовать его XSLT к следующему XML:

<graph> 
<node id="a"> 
    <link id="link1" to="b"> 
</node> 
<node id="b"> 
    <link id="link2" to="d"> 
</node><node id="c"> 
<node id="c"/> 
<node id="d"> 
    <link id="link3" to="c"> 
</node> 
</graph> 

я написал XSLT, который включает все следующую часть:

<xsl:template match="//node"> 
    <xsl:element name="link"> 
      <xsl:attribute name="to"> 
       <xsl:value-of select="//link[@from = self::node()/@id]/@to"></xsl:value-of> 
      </xsl:attribute> 
    <xsl:apply-templates />  
    </xsl:element> 


</xsl:template> 

но это не сработало. что я делаю неправильно?

ответ

1

Ваш XSLT создает только link элементов, но вам необходимо как-то создать и node элементов. Кроме того, self::node() в предикате не работает так, как вы ожидаете. Вместо этого используйте функцию current().

Чтобы решить вашу задачу, рекомендуется начать с преобразования идентичности и добавить шаблоны для узлов, которым требуется специальная обработка. Вот пример:

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

<xsl:template match="graph"> 
    <xsl:copy> 
     <!-- Only process node children --> 
     <xsl:apply-templates select="node"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="node"> 
    <xsl:copy> 
     <!-- Also process matching links --> 
     <xsl:apply-templates select="@* | //link[@from = current()/@id]"/> 
    </xsl:copy> 
</xsl:template> 

<!-- Don't copy @from attribute of links --> 
<xsl:template match="link/@from"/>