transformações recursiva usando XSLT, XPath: documento () e mediawiki
Pergunta
Eu quero usar o wikipedia API para encontrar as páginas franceses, incluindo o ' ' Template: Infobox Scientifique '' faltando na versão Inglês. Portanto, a minha ideia era para processar o seguinte documento com xproc:
e a seguinte folha de estilo 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,' ','_')"/>
<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('http://fr.wikipedia.org/w/api.php?action=query&format=xml&prop=langlinks&lllimit=500&titles=',translate($title,' ','_'))"/>
<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>
O extrato XSLT todos os artigos que contêm o modelo e para cada artigo que eu queria chamar wikipedia para obter as ligações entre os wikis. Aqui, o modelo englishTitle chama a função XPath documento () .
Mas ele sempre diz que count(ll)=1
enquanto há muitos nós. (Por exemplo http: //fr.wikipedia. org / w / api.php? action = consulta & format = xml & prop = langlinks & lllimit = 500 & títulos = Carl Sagan ).
Eu não posso processar os nós devolvidos pela documento () função?
Solução
Você deve tentar:
<xsl:value-of select="count(document($uri1)/api/query/pages/page/langlinks/ll)"/>
Em uma nota diferente - o que é
translate(@title,' ','_')
isso quer dizer? O que há de errado com:
translate(@title, ' ', '_')
Não há necessidade de aspas simples codificar em atributos XML a menos que você quiser usar um tipo de citação que delimita o valor do atributo. Todos estes são válidos:
name="foo"'foo"
name='foo'"foo'
Toda a sua transformação pode ser reduzida para algo como isto:
<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&format=xml&prop=langlinks&lllimit=500&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> </xsl:text>
<xsl:text>count=</xsl:text>
<xsl:value-of select="count($doc/api/query/pages/page/langlinks/ll)"/>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="text()" />
</xsl:stylesheet>
Deixe os modelos XSLT padrão trabalhar para você - eles fazem toda a recursão no fundo, tudo que você tem a fazer é pegar os nós que deseja processo (e impedir a saída de texto desnecessário, substituindo o modelo text()
padrão com um um vazio).