XPATH / XSLT: выбор узла, где атрибут родительского узла совпадает с атрибутом другого узла - PullRequest
5 голосов
/ 29 марта 2011

Я пытаюсь применить преобразование к приведенному ниже 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>

Я изо всех сил пытаюсь найти способ выбора значения узла, атрибут родительского узла которого совпадает со значением атрибута другого узла.Например, для автора Джона Смита я бы хотел выбрать значение узла, в котором совпадает идентификатор филиала.

Пока у меня есть некоторый код в моей таблице стилей, как показано ниже, но я знаю выбор внутриузел не работает.

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

Как выбрать правильное название организации для связанного автора?

Большое спасибо

Джим

Ответы [ 4 ]

7 голосов
/ 29 марта 2011

В качестве альтернативы использованию переменной вы можете использовать оператор 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>
4 голосов
/ 29 марта 2011

Ключи являются правильным инструментом для перекрестных ссылок. Эта таблица стилей:

<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>
2 голосов
/ 29 марта 2011

Просто быстрый ответ ... надеюсь, это поможет, не могу запустить его сам в данный момент: -S вы можете поместить идентификатор в переменную, например:

<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>
1 голос
/ 29 марта 2011
<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>


Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...