代码之家  ›  专栏  ›  技术社区  ›  darune

合并和继承参数

  •  0
  • darune  · 技术社区  · 7 年前

    我有如下的东西

    <root>
      <template ID='1'>
        <params>
          <a>1</a>
          <b>1</b>
        </params>
      </template>
    
      <document1 templateID='1'>
        <params>
          <b>4</b>
          <c>5</c>
        </params>
      </document1>
    
    </root>
    

      <root>
        <document1 templateID='1'>
          <params>
            <a>1</a>
            <b>4</b>
            <c>5</c>
          </params>
        </document1>
      </root>
    

    在示例参数中 a 从模板继承,而参数 b c 在模板中未知或未设置。它类似于继承或css的工作方式。我希望你明白我的意思。在开始这项任务之前,我认为这不应该太难(仍然希望我只是忽略了一些东西)。

    我试过把两个节点集连在一起(用 nodeset1 , nodeset2 为了保留顺序),并使用基于前面同级名称的“选择”/“筛选”-但此策略似乎不起作用,因为它们似乎不是实际同级。这可以由一个聪明的小组来完成吗?能做到吗(我认为可以)

    我正在使用xslt版本3.0(saxon)

    1 回复  |  直到 7 年前
        1
  •  1
  •   Martin Honnen    7 年前

    我认为您想要分组或合并,在xslt3中合并是最好的选择

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        exclude-result-prefixes="#all"
        version="3.0">
    
      <xsl:output indent="yes"/>
    
      <xsl:mode on-no-match="shallow-copy"/>
    
      <xsl:key name="template-by-id" match="template" use="@ID"/>
    
      <xsl:template match="template"/>
    
      <xsl:template match="*[@templateID]/params">
          <xsl:copy>
              <xsl:merge>
                  <xsl:merge-source name="template" select="key('template-by-id', ../@templateID)/params/*">
                      <xsl:merge-key select="string(node-name())"/>
                  </xsl:merge-source>
                  <xsl:merge-source name="doc" select="*">
                      <xsl:merge-key select="string(node-name())"/>
                  </xsl:merge-source>
                  <xsl:merge-action>
                      <xsl:copy-of select="(current-merge-group('doc'), current-merge-group('template'))[1]"/>
                  </xsl:merge-action>
              </xsl:merge>
          </xsl:copy>
      </xsl:template>
    
    </xsl:stylesheet>
    

    https://xsltfiddle.liberty-development.net/jyH9rN8/

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        exclude-result-prefixes="#all"
        version="3.0">
    
      <xsl:output indent="yes"/>
    
      <xsl:mode on-no-match="shallow-copy"/>
    
      <xsl:key name="template-by-id" match="template" use="@ID"/>
    
      <xsl:template match="template"/>
    
      <xsl:template match="*[@templateID]/params">
          <xsl:copy>
              <xsl:for-each-group select="key('template-by-id', ../@templateID)/params/*, *" group-by="node-name()">
                  <xsl:copy-of select="head((current-group()[2], .))"/>
              </xsl:for-each-group>
          </xsl:copy>
      </xsl:template>
    
    </xsl:stylesheet>
    

    https://xsltfiddle.liberty-development.net/jyH9rN8/1

    xsl:merge 需要在任何合并键上对输入进行排序,或者首先对输入进行排序,上面的分组更简单、更可靠,除非 params