每个后代的每个人

时间:2018-03-26 00:13:26

标签: xslt xslt-2.0

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

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

    &#13;
    &#13;
    <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>
    &#13;
    &#13;
    &#13;

    输出

    &#13;
    &#13;
    <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>
    &#13;
    &#13;
    &#13;

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

    &#13;
    &#13;
    <?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>
    &#13;
    &#13;
    &#13;

    这是我的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>
    

1 个答案:

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

你应该得到你想要的东西。