Реквизивные преобразования с использованием xslt, xpath: document () и mediawiki - PullRequest
0 голосов
/ 14 июля 2009

Я хочу использовать API Википедии , чтобы найти французские страницы, в том числе '' 1003 * Шаблон: Infobox Scientifique '', отсутствующий в английской версии. Итак, моя идея заключалась в том, чтобы обработать следующий документ с помощью xproc:

http://fr.wikipedia.org/w/api.php?action=query&format=xml&list=embeddedin&eititle=Template:Infobox%20Scientifique&eilimit=400

и следующая таблица стилей xslt:

<?xml version='1.0' ?>
<xsl:stylesheet
    xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
    version='1.0'
    >
<xsl:output method='text' indent="yes"/> 
<xsl:template match="/">
<xsl:apply-templates select="api"/>
</xsl:template>

<xsl:template match="api">
<xsl:for-each select="query/embeddedin/ei">
<xsl:variable name="title" select="translate(@title,&apos; &apos;,&apos;_&apos;)"/>
<xsl:variable name="english-title">
<xsl:call-template name="englishTitle"><xsl:with-param name="title" select="@title"/></xsl:call-template>
</xsl:variable>

<xsl:value-of select="$english-title"/><xsl:text>
</xsl:text>

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

<xsl:template name="englishTitle">
<xsl:param name="title"/>
<xsl:variable name="uri1" select="concat(&apos;http://fr.wikipedia.org/w/api.php?action=query&amp;format=xml&amp;prop=langlinks&amp;lllimit=500&amp;titles=&apos;,translate($title,&apos; &apos;,&apos;_&apos;))"/>
<xsl:message><xsl:value-of select="$uri1"/></xsl:message>
<xsl:message>count=<xsl:value-of select="count(document($uri1,/api/query/pages/page/langlinks/ll))"/></xsl:message>
</xsl:template>

</xsl:stylesheet>

XSLT извлекает все статьи, содержащие Шаблон, и для каждой статьи я хотел позвонить в Википедию, чтобы получить ссылки между вики. Здесь шаблон englishTitle вызывает функцию xpath document () .

Но это всегда говорит, что count(ll)=1, тогда как есть множество узлов. (например, http://fr.wikipedia.org/w/api.php?action=query&format=xml&prop=langlinks&lllimit=500&titles=Carl_Sagan).

Не могу ли я обработать узлы, возвращенные функцией document () ?

1 Ответ

1 голос
/ 14 июля 2009

Вы должны попробовать:

<xsl:value-of select="count(document($uri1)/api/query/pages/page/langlinks/ll)"/>

На другой ноте - что такое

translate(@title,&apos; &apos;,&apos;_&apos;)

должно означать? Что не так с:

translate(@title, ' ', '_')

Нет необходимости кодировать одинарные кавычки в атрибутах XML, если вы не хотите использовать тип кавычки, который разделяет значение атрибута. Все они действительны:

name="foo&quot;'foo"
name='foo&apos;"foo'

Вся ваша трансформация может быть сведена к следующему:

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
  <xsl:output method="text" /> 

  <xsl:param name="baseUrl" select="'http://fr.wikipedia.org/w/api.php?action=query&amp;format=xml&amp;prop=langlinks&amp;lllimit=500&amp;titles='" />

  <xsl:template match="ei">
    <xsl:variable name="uri" select="concat($baseUrl ,translate(@title,' ','_'))"/>
    <xsl:variable name="doc" select="document($uri)"/>

    <xsl:value-of select="$uri"/>
    <xsl:text>&#10;</xsl:text>

    <xsl:text>count=</xsl:text>
    <xsl:value-of select="count($doc/api/query/pages/page/langlinks/ll)"/>
    <xsl:text>&#10;</xsl:text>
  </xsl:template>

  <xsl:template match="text()" />  
</xsl:stylesheet>

Позвольте шаблонам XSLT по умолчанию работать на вас - они выполняют всю рекурсию в фоновом режиме, все, что вам нужно сделать, это перехватить узлы, которые вы хотите обработать (и предотвратить вывод ненужного текста, переопределив шаблон text() по умолчанию с пустым).

...