XPATH/XSLT:选择父节点的属性与其他节点的属性相匹配的节点

问题描述:

我试图使用XPath和XSLT将转换应用于下面的XML。XPATH/XSLT:选择父节点的属性与其他节点的属性相匹配的节点

<AuthorGroup> 
    <Author AffiliationID="A1"> 
    <GivenName>John</GivenName> 
    <Initials/> 
    <FamilyName>Smith</FamilyName> 
    <Degrees/> 
    <Roles/> 
    </Author> 
    <Author AffiliationID="A2"> 
    <GivenName>Bill</GivenName> 
    <Initials/> 
    <FamilyName>Atkins</FamilyName> 
    <Degrees/> 
    <Roles/> 
    </Author> 
    <Affiliation AFFID="A1"> 
    <OrgDivision/> 
    <OrgName>Some Org</OrgName> 
    <OrgAddress/> 
    </Affiliation> 
    <Affiliation AFFID="A2"> 
    <OrgDivision/> 
    <OrgName>Another Org</OrgName> 
    <OrgAddress/> 
    </Affiliation> 
</AuthorGroup> 

我想作者及单位名称一个节点下的结合,所以我会用如下的结构结束:

<AUG> 
    <AU><NAME>John Smith</NAME><AUINFO>Some Org</AUINFO></AU> 
    <AU><NAME>Bill Atkins</NAME><AUINFO>Another Org</AUINFO></AU> 
</AUG> 

我苦苦寻找选择的一种方式父节点属性的节点的值与另一个节点的属性的值匹配。例如,对于作者John Smith,我想选择联属ID匹配的节点的值。

到目前为止,我在我的样式表中有一些代码,如下所示,但我知道节点内的选择不起作用。

<xsl:for-each select="AuthorGroup/Author"> 
    <AU> 
    <NAME><xsl:value-of select="./FamilyName" /> <xsl:value-of select="./GivenName" /></NAME> 
    <AUINFO><xsl:value-of select="../Affiliation[@AFFID='NEED TO MATCH AUTHOR AFFILIATIONID']/OrgName" /> </AUINFO> 


    </AU>   
</xsl:for-each> 

我应该如何为关联作者选择正确组织名称的值?

非常感谢

吉姆

+1

检查使用特定的XSLT功能的交叉引用我的回答。 – 2011-03-29 16:37:26

作为替代使用一个变量,你可以使用“当前()”操作符来获得你在

<xsl:value-of select="../Affiliation[@AFFID=current()/@AffiliationID]/OrgName"/> 

因此目前的作者节点,如果采取以下样式表

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:template match="/"> 
     <AUG> 
     <xsl:for-each select="AuthorGroup/Author"> 
      <AU> 
       <NAME> 
        <xsl:value-of select="./FamilyName"/> 
        <xsl:value-of select="./GivenName"/> 
       </NAME> 
       <AUINFO> 
        <xsl:value-of select="../Affiliation[@AFFID=current()/@AffiliationID]/OrgName"/> 
       </AUINFO> 
      </AU> 
     </xsl:for-each> 
     </AUG> 
    </xsl:template> 
</xsl:stylesheet> 

并把它给你的XML,结果应该是像这样

<AUG> 
    <AU> 
     <NAME>SmithJohn</NAME> 
     <AUINFO>Some Org</AUINFO> 
    </AU> 
    <AU> 
     <NAME>AtkinsBill</NAME> 
     <AUINFO>Another Org</AUINFO> 
    </AU> 
</AUG> 
+0

这工作完美。谢谢 – JimS 2011-03-29 13:43:13

只是一个快速的答案...希望这有助于无法运行它自己的时刻:-S 你可以把ID在一个变量,如:

<xsl:for-each select="AuthorGroup/Author"> 
    <xsl:variable name="affID" select="@AFFID" /> 
    <AU> 
    <NAME><xsl:value-of select="./FamilyName" /> <xsl:value-of select="./GivenName" /></NAME> 
    <AUINFO><xsl:value-of select="../Affiliation[@AFFID=$affID]/OrgName" /> </AUINFO> 
    </AU>   
</xsl:for-each> 

<xsl:for-each select="AuthorGroup/Author"> 
    <AU> 
    <NAME><xsl:value-of select="./FamilyName" /> <xsl:value-of select="./GivenName" /> 
    </NAME> 
    <AUINFO><xsl:value-of select="../Affiliation[@AFFID=./@AffiliationID]/OrgName" /> 
    </AUINFO> 


+0

嘿奈良。感谢您的回答。我无法让它起作用,因此取而代之。在Tim提出的current()运算符的XPath表达式中。 – JimS 2011-03-29 13:45:33

键是交叉引用的工具。这个样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:strip-space elements="*"/> 
    <xsl:key name="kAffiliationByAFFID" match="Affiliation" use="@AFFID"/> 
    <xsl:template match="AuthorGroup"> 
     <AUG> 
      <xsl:apply-templates/> 
     </AUG> 
    </xsl:template> 
    <xsl:template match="Author"> 
     <AU> 
      <NAME> 
       <xsl:value-of select="concat(GivenName,' ',FamilyName)"/> 
      </NAME> 
      <xsl:apply-templates 
       select="key('kAffiliationByAFFID',@AffiliationID)" 
       mode="out"/> 
     </AU> 
    </xsl:template> 
    <xsl:template match="Affiliation"/> 
    <xsl:template match="Affiliation" mode="out"> 
     <AUINFO> 
      <xsl:apply-templates/> 
     </AUINFO> 
    </xsl:template> 
</xsl:stylesheet> 

输出:

<AUG> 
    <AU> 
     <NAME>John Smith</NAME> 
     <AUINFO>Some Org</AUINFO> 
    </AU> 
    <AU> 
     <NAME>Bill Atkins</NAME> 
     <AUINFO>Another Org</AUINFO> 
    </AU> 
</AUG> 
+1

我的直觉本来是@Tim C的解决方案,但这样好多了。 – 2011-03-29 19:23:07

+0

谢谢亚历杭德罗。我以前没有使用过xslt键,所以才会开始了解它们。 – JimS 2011-03-30 10:09:44

+0

@lwburk你为什么认为这个解决方案好得多?我会对细节感兴趣。谢谢。 – JimS 2011-03-30 10:10:52