从动态创建的兄弟元素访问属性

时间:2017-03-03 13:10:42

标签: xslt-2.0

学习XSLT!

我有一个XML源代码树片段,如下所示:

使用Saxon和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>

我需要提供什么作为谓词值才能逐步执行属性值?

非常感谢

1 个答案:

答案 0 :(得分: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>