【问题标题】:for-each for each descendant对于每个后代
【发布时间】:2018-03-26 00:13:25
【问题描述】:

我正在尝试使用 xslt 2.0/1.0 构建以下逻辑:

  1. for-each *[@name=summary] 转到父级并查找所有后代 <info> 元素(@name=summary 除外)
  2. for-each info/@id 访问 @id 的文档 uri。并打印 xml 文档中的 <name> 元素。
  3. 如果@name=summary@level=top,不要处理<info>@duplicate=yes

XML

<map>
   <info id="a.xml" level="top" name="summary"/>
   <map id="b.xml">
      <info id="c.xml" name="summary">
         <info id="1.xml"/>
         <info id="2.xml"/>
      </info>
   </map>
   <map id="d.xml">
      <info id="e.xml" name="summary">
         <info id="1.xml" duplicate="yes"/>
         <info id="4.xml"/>
         <info id="2.xml" duplicate="yes"/>
      </info>
   </map>
   <map id="f.xml">
      <info id="g.xml" name="summary">
         <info id="2.xml" duplicate="yes"/>
         <info id="1.xml" duplicate="yes"/>
         <info id="5.xml"/>
      </info>
   </map>
   <info id="h.xml" level="top" name="summary"/>
</map>

输出

<result>
    <summary id="a.xml" level="top">
        <info id="1.xml">one</info>
        <info id="2.xml">two</info>
        <info id="4.xml">four</info>
        <info id="5.xml">five</info>
    </summary>
    <summary id="c.xml">
        <info id="1.xml">one</info>
        <info id="2.xml">two</info>
    </summary>
    <summary id="e.xml">
        <info id="1.xml">one</info>
        <info id="4.xml">four</info>
        <info id="2.xml">two</info>
    </summary>
    <summary id="g.xml">
        <info id="2.xml">two</info>
        <info id="1.xml">one</info>
        <info id="5.xml">five</info>
    </summary>
    <summary id="h" level="top">
        <info id="1.xml">one</info>
        <info id="2.xml">two</info>
        <info id="4.xml">four</info>
        <info id="5.xml">five</info>
    </summary>
</result>

1.xml、2.xml、4.xml、5.xml、a.xml、b.xml...具有相似的结构(见下方评论)

<?xml version="1.0" encoding="UTF-8"?>
<input>
    <name>one</name>
    <!-- 2.xml <name>two</name>, 4.xml <name>four</name>, 5.xml <name>five</name>, a.xml <name>a</name> ......    -->
</input>

这是我的 xslt,它没有给出正确的输出:

 <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="this" select="/"/>
<xsl:template match="/">
    <result>
        <xsl:apply-templates/>
    </result>
</xsl:template>
<xsl:template match="*[@name = 'summary']">
    <summary>
        <xsl:copy-of select="@id"/>
        <xsl:copy-of select="@level"/>
        <xsl:copy-of select="@name"></xsl:copy-of>
        <xsl:call-template name="createsummary"/>
    </summary>
</xsl:template>
<xsl:template name="createsummary">
    <xsl:for-each select="../descendant::*">
        <xsl:for-each select="doc(resolve-uri(@id, document-uri($this)))/*">
            <xsl:if test="*[name() = 'name']">
                <xsl:copy-of select="name"/>
            </xsl:if>
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

【问题讨论】:

    标签: xslt xslt-2.0


    【解决方案1】:

    我没有尝试设置目录结构,但正确的 info 元素是由

    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
        <xsl:variable name="this" select="/"/>
    
        <xsl:output indent="yes"/>
        <xsl:strip-space elements="*"/>
    
        <xsl:template match="/">
            <result>
                <xsl:apply-templates/>
            </result>
        </xsl:template>
    
        <xsl:template match="*[@name = 'summary']">
            <summary>
                <xsl:copy-of select="@id"/>
                <xsl:copy-of select="@level"/>
                <xsl:copy-of select="@name"></xsl:copy-of>
                <xsl:apply-templates select="." mode="create-summary"/>
            </summary>
        </xsl:template>
    
        <xsl:template match="*[@name = 'summary' and @level = 'top']" mode="create-summary">
            <xsl:apply-templates select="../descendant::info[not(@name = 'summary') and not(@duplicate = 'yes')] except ." mode="summary"/>
        </xsl:template>
    
        <xsl:template match="*[@name = 'summary' and not(@level = 'top')]" mode="create-summary">
            <xsl:apply-templates select="../descendant::info[not(@name = 'summary')] except ." mode="summary"/>
        </xsl:template>
    
        <xsl:template match="info" mode="summary">
            <info id="{@id}"></info>
        </xsl:template>
    
    </xsl:stylesheet>
    

    表示结果是

    <?xml version="1.0" encoding="UTF-8"?>
    <result>
       <summary id="a.xml" level="top" name="summary">
          <info id="1.xml"/>
          <info id="2.xml"/>
          <info id="4.xml"/>
          <info id="5.xml"/>
       </summary>
       <summary id="c.xml" name="summary">
          <info id="1.xml"/>
          <info id="2.xml"/>
       </summary>
       <summary id="e.xml" name="summary">
          <info id="1.xml"/>
          <info id="4.xml"/>
          <info id="2.xml"/>
       </summary>
       <summary id="g.xml" name="summary">
          <info id="2.xml"/>
          <info id="1.xml"/>
          <info id="5.xml"/>
       </summary>
       <summary id="h.xml" level="top" name="summary">
          <info id="1.xml"/>
          <info id="2.xml"/>
          <info id="4.xml"/>
          <info id="5.xml"/>
       </summary>
    </result>
    

    因此,您可以使用其他文件更改模板

        <xsl:template match="info" mode="summary">
            <info id="{@id}"></info>
        </xsl:template>
    

        <xsl:template match="info" mode="summary">
            <info id="{@id}">
               <xsl:value-of select="doc(resolve-uri(@id, document-uri($this)))/*/name"/>
            </info>
        </xsl:template>
    

    你应该得到你想要的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-28
      • 1970-01-01
      • 2016-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-20
      相关资源
      最近更新 更多