【问题标题】:Recursive transformations using xslt, xpath:document() and mediawiki使用 xslt、xpath:document() 和 mediawiki 进行递归转换
【发布时间】:2009-07-14 17:13:35
【问题描述】:

我想使用Wikipedia API 查找法语页面,包括英文版中缺少的“SQLTemplate: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 提取包含模板的所有文章,对于每篇文章,我想调用 Wikipedia 以获取 wiki 之间的链接。这里的模板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()函数返回的节点吗?

【问题讨论】:

    标签: api xslt xpath mediawiki wikipedia


    【解决方案1】:

    你应该试试:

    <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() 模板来防止输出不必要的文本一个空的)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-15
      • 2014-06-14
      相关资源
      最近更新 更多