2017-03-03 147 views
1

学习XSLT访问属性!从动态创建的兄弟元素

我有一个XML源代码树的片段,看起来像这样:

使用撒克逊和XSLT 2.0变换...

<?xml version = "1.0" encoding = "UTF-8"?> 
    <Chapter revision="B" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
     <Content Ref="X123"> 
      <Ref name="INT1"/> 
      <Ref name="INT2"/> 
      <Ref name="INT3"/> 
      <Ref name="INT4"/> 
      <Ref name="INT5"/> 
     </Content> 
     <Data> 
      <Reference name="INT1" Function="CONDUCTOR"></Reference> 
      <Reference name="INT2" Function="SIGNAL"></Reference> 
      <Reference name="INT3" Function="MIXED"></Reference> 
      <Reference name="INT4" Function="PLANE"></Reference> 
      <Reference name="INT5" Function="CORE"></Reference> 
     </Data> 
    </Chapter> 

我希望它产生这样的:

<Chapter> 
    <Content> 
     <Ref id="INT1" Function="CONDUCTOR">INT1</Ref> 
     <Ref id="INT2" Function="SIGNAL">INT2</Ref> 
     <Ref id="INT3" Function="MIXED">INT3</Ref> 
     <Ref id="INT4" Function="PLANE">INT4</Ref> 
     <Ref id="INT5" Function="CORE">INT5</Ref> 
    </Content> 
</Chapter> 

这里是我的模板片段:

<xsl:template match="/"> 
    <xsl:apply-templates select="/Chapter"/> 
</xsl:template> 

<xsl:template match="/Chapter"> 
    <xsl:element name="{name()}"> 
     <xsl:apply-templates select="Content"/> 
    </xsl:element> 
</xsl:template> 

<xsl:template match="Content"> 
    <xsl:element name="{name()}"> 
     <xsl:apply-templates select="Ref"/> 
    </xsl:element> 
</xsl:template> 

<xsl:template match="Ref"> 
    <xsl:element name="{name()}"> 

     <xsl:attribute name="id"> 
      <xsl:value-of select="@name"/> 
     </xsl:attribute> 

     <xsl:attribute name="Function"> 
      <xsl:value-of select="/Chapter/Data/Reference[@name=/Chapter/Data/Reference/@name]/@Function"/> 
     </xsl:attribute> 

     <xsl:value-of select="@name"/> 

    </xsl:element> 
</xsl:template> 

但上面的模板会产生这样的: 这显然是从每一个节点

<Chapter> 
     <Content> 
      <Ref id="INT1" Function="CONDUCTOR SIGNAL MIXED PLANE CORE">INT1</Ref> 
      <Ref id="INT2" Function="CONDUCTOR SIGNAL MIXED PLANE CORE">INT2</Ref> 
      <Ref id="INT3" Function="CONDUCTOR SIGNAL MIXED PLANE CORE">INT3</Ref> 
      <Ref id="INT4" Function="CONDUCTOR SIGNAL MIXED PLANE CORE">INT4</Ref> 
      <Ref id="INT5" Function="CONDUCTOR SIGNAL MIXED PLANE CORE">INT5</Ref> 
     </Content> 
    </Chapter> 

我需要什么提供的预测值来逐步属性值拿起值?

非常感谢

回答

0

变化/Chapter/Data/Reference[@name=/Chapter/Data/Reference/@name]/@Function/Chapter/Data/Reference[@name=current()/@name]/@Function,然后了解键和确定<xsl:key name="ref" match="Data/Reference" use="@name"/>和使用key('ref', @name)/@Function而是以提高性能和可读性。

一般来说,你可能想了解文字结果元素和属性值模板,以便

<xsl:template match="Ref"> 
    <xsl:element name="{name()}"> 

     <xsl:attribute name="id"> 
      <xsl:value-of select="@name"/> 
     </xsl:attribute> 

     <xsl:attribute name="Function"> 
      <xsl:value-of select="/Chapter/Data/Reference[@name=/Chapter/Data/Reference/@name]/@Function"/> 
     </xsl:attribute> 

     <xsl:value-of select="@name"/> 

    </xsl:element> 
</xsl:template> 

成为

<xsl:template match="Ref"> 
    <Ref id="{@name}" Function="{key('ref', @name)/@Function}"> 
     <xsl:value-of select="@name"/> 
    </Ref> 
</xsl:template> 

和完整的代码是

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="xs" 
    version="2.0"> 

    <xsl:key name="ref" match="Data/Reference" use="@name"/> 

    <xsl:template match="/Chapter"> 
     <xsl:copy copy-namespaces="no"> 
      <xsl:apply-templates select="Content"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Content"> 
     <xsl:copy copy-namespaces="no"> 
      <xsl:apply-templates/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Ref"> 
     <Ref id="{@name}" Function="{key('ref', @name)/@Function}"> 
      <xsl:value-of select="@name"/> 
     </Ref> 
    </xsl:template> 

</xsl:stylesheet> 
+0

马丁,许多感谢您的解决方案。精美的作品。而感谢你的其他建议,并指着我研究的其他领域。非常感谢您的时间和麻烦! Ralph –

+0

我用你的建议:/ Chapter/Data/Reference [@ name = current()/ @ name]/@ Function –

+0

Martin,我用你的建议 /Chapter/Data/Reference [@ name = current )/ @名称]/@功能 并能正常工作。我如何获得与以前的名字相关的功能?我已经使用 [@名称=前同辈:: * [1]/@名称]试图 于断言 但它没有返回。难道电流()具有相同的上下文前同辈? 拉尔夫乙 –