繁体   English   中英

XPATH / XSLT:选择父节点的属性与另一个节点的属性匹配的节点

[英]XPATH / XSLT: Selecting a node where the parent node's attribute matches the attribute of another node

我正在尝试使用XPath和XSLT将转换应用于下面的XML。

<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>

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

非常感谢

吉姆

作为使用变量的替代方法,您可以使用“current()”运算符来获取您所在的当前Author节点

<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>

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

<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>

只是一个快速回答...希望这有帮助,暂时不能自己运行:-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>


暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM