【问题标题】:How do I merge and concatenate the data from each row in two separate source files?如何合并和连接两个单独源文件中每一行的数据?
【发布时间】:2012-05-17 15:30:41
【问题描述】:

我有两个源文件需要逐行合并。我很高兴将文件读入一个变量,我对逻辑很满意,但语法让我很难过。对于文件 1 中的每一行,我需要对文件 2 中的每一行进行循环并输出连接在一起的两个变量:

文件 1:

<rows>
    <row>1</row>
    <row>2</row>
    <row>3</row>
    <row>4</row>
</rows>

文件 2:

<rows>
    <row>a</row>
    <row>b</row>
</rows>

需要的输出:

<rows>
    <row>1/a</row>
    <row>1/b</row>
    <row>2/a</row>
    <row>2/b</row>
    <row>3/a</row>
    <row>3/b</row>
    <row>4/a</row>
    <row>4/b</row>
<rows>

我(糟糕的)尝试让 XSLT 工作:

<rows>
    <xsl:apply-templates select="document('file1.xml')/rows/row" />
</rows>

<xsl:template match="row">
    <xsl:apply-templates select="document('file2.xml')/rows/row" />
</xsl:template>  

<xsl:template match="row">
    <row><xsl:value-of select="???" />/<xsl:value-of select="???" /></row>
</xsl:template>

(这些文件是我实际拥有的文件的简化版本)

如何使一个模板匹配一个“行”值而另一个匹配另一个(两个源文件使用相同的结构)。我该如何设置那些'???'价值观?

【问题讨论】:

    标签: xslt-2.0 saxon


    【解决方案1】:
    <xsl:stylesheet version="2.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>
    
     <xsl:variable name="vDoc2">
        <rows>
            <row>a</row>
            <row>b</row>
        </rows>
     </xsl:variable>
    
     <xsl:template match="node()|@*">
      <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
     </xsl:template>
    
     <xsl:template match="/*">
      <rows>
        <xsl:apply-templates/>
      </rows>
     </xsl:template>
    
     <xsl:template match="row">
       <xsl:apply-templates select="$vDoc2/*/row" mode="doc2">
         <xsl:with-param name="pValue" select="."/>
       </xsl:apply-templates>
     </xsl:template>
    
     <xsl:template match="row" mode="doc2">
       <xsl:param name="pValue" />
    
       <row><xsl:sequence select="concat($pValue, '/', .)"/></row>
     </xsl:template>
    </xsl:stylesheet>
    

    当此转换应用于提供的第一个 XML 文档时:

    <rows>
        <row>1</row>
        <row>2</row>
        <row>3</row>
        <row>4</row>
    </rows>
    

    产生了想要的正确结果:

    <rows>
       <row>1/a</row>
       <row>1/b</row>
       <row>2/a</row>
       <row>2/b</row>
       <row>3/a</row>
       <row>3/b</row>
       <row>4/a</row>
       <row>4/b</row>
    </rows>
    

    【讨论】:

    • 我知道它是如何工作的,你能解释一下这部分是做什么的吗:&lt;xsl:template match="node()|@*"&gt;...&lt;/xsl:template&gt;
    • @TheArtfulBenny:这就是著名的身份规则——使用和覆盖身份模板是最基本和最强大的XSLT 设计模式。这使得为​​诸如“按原样”复制大多数节点以及更改、删除、替换或添加一些特定节点等任务提供简单、简短和简单的解决方案成为可能。您可以在此处阅读有关此主题的更多信息(推荐):dpawson.co.uk/xsl/sect2/identity.html
    • @TheArtfulBenny:是的,它让事情变得如此简单——也很好地展示了 XSLT 的主要架构思想。
    猜你喜欢
    • 1970-01-01
    • 2019-03-07
    • 2013-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-26
    • 1970-01-01
    • 2019-07-25
    相关资源
    最近更新 更多