合并XSLT中的两个节点

时间:2017-03-03 09:55:58

标签: xml xslt xslt-1.0

有几天我很难找到解决这个问题的方法。 我有这个XML:

<?xml version="1.0" encoding="iso-8859-1"?>
<Einreichung>
    <EinreichZahlung>
		<EinreichZahlungen>
			<MemberFirstName>JOHN</MemberFirstName>
			<MemberLastName>DOE</MemberLastName>
			<MemberLogin>1</MemberLogin>
			<Store>0180</Store>
		</EinreichZahlungen>
    </EinreichZahlung>
	<EinreichZahlung>
		<EinreichZahlungen>
			<MemberFirstName>DAVID</MemberFirstName>
			<MemberLastName>GREEN</MemberLastName>
			<MemberLogin>2</MemberLogin>
			<Store>0181</Store>
		</EinreichZahlungen>
    </EinreichZahlung>
    <EinreichPerson>
		<PersonBelege>
			<Belege>
				<MemberFirstName>JANE</MemberFirstName>
				<MemberLastName>DOE</MemberLastName>
				<MemberLogin>1</MemberLogin>
				<Store>0180</Store>
			</Belege>
			<Belege>
				<MemberFirstName>JANE</MemberFirstName>
				<MemberLastName>DOE</MemberLastName>
				<MemberLogin>1</MemberLogin>
				<Store>0180</Store>
			</Belege>
		</PersonBelege>
    </EinreichPerson>
    <EinreichPerson>
		<PersonBelege>
			<Belege>
				<MemberFirstName>DAVID</MemberFirstName>
				<MemberLastName>GREEN</MemberLastName>
				<MemberLogin>2</MemberLogin>
				<Store>0181</Store>
			</Belege>
		</PersonBelege>
    </EinreichPerson>
</Einreichung>

我需要根据 Store 值将两个节点合并为一个XSLT,以便最终的HTML看起来像这样:

<pre><b>
Zahlung 1080: JOHN DOE
Belege 1080: details...

Zahlung 1081: DAVID GREEN
Belege 1081: details...
</b></pre>

我是XSLT的新手,所以我将非常感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

在处理节点时,您可以使用xpath表达式在xml树中找到任何节点。为了加快速度,最好创建一个密钥,使用&#34;匹配&#34;属性设置为您要查找的元素标记,&#34;使用&#34;属性作为索引。

type exitStatusMsg struct {
    Status uint32
}

// RFC 4254 Section 6.5.
type execMsg struct {
    Command string
}

go func(in <-chan *ssh.Request, channel ssh.Channel) {
        for req := range in {
            if req.Type == "exec" {
                var msg execMsg
                if err := ssh.Unmarshal(req.Payload, &msg); err != nil {
                    log.Printf("error parsing ssh execMsg: %s\n", err)
                    req.Reply(false, nil)
                    return
                }
                go func(msg execMsg, ch ssh.Channel) {
                    // ch can be used as a ReadWriteCloser if there should be interactivity
                    runYourCommand(msg.Command, ch)
                    ex := exitStatusMsg{
                        Status: 0,
                    }
                    // return the status code
                    if _, err := ch.SendRequest("exit-status", false, ssh.Marshal(&ex)); err != nil {
                        log.Printf("unable to send status: %v", err)
                    }
                    ch.Close()
                }(msg, channel)
                req.Reply(true, nil) // tell the other end that we can run the request
            } else {
                req.Reply(req.Type == "shell", nil)
            }
        }
    }(requests, channel)

定义变量可能有助于提高易读性(使用Belege [1],因为你似乎有2个Belege节点用于存储180,尽管这个问题要求合并2个节点)

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>

<xsl:key name="belege-by-store" match="Belege" use="Store" />

<xsl:template match="/Einreichung">
    <xsl:apply-templates select="EinreichZahlung/EinreichZahlungen" />
</xsl:template>


<xsl:template match="EinreichZahlungen">
  <pre>
    <b>
      <xsl:value-of select="MemberFirstName" /><xsl:text> </xsl:text>
      <xsl:value-of select="MemberLastName" /><xsl:text> </xsl:text>
      <xsl:value-of select="key('belege-by-store', Store)/MemberFirstName" />
     </b>
  </pre>
</xsl:template>
</xsl:stylesheet>

更新

您可以使用以下内容处理每个Belege:

<xsl:template match="EinreichZahlungen"> 
 <xsl:variable name="belegeNodes">    
 <xsl:copy-of select="key('belege-by-store', Store)" />
 </xsl:variable>
   <pre>
   <b>  
   <xsl:value-of select="MemberFirstName" />
   <xsl:text> </xsl:text>   
   <xsl:value-of select="MemberLastName" />
   <xsl:text> </xsl:text>   
   <xsl:value-of select="$belegeNodes/Belege[1]/MemberFirstName" />     
   </b>  
   </pre>
</xsl:template>

或(与Belege的另一个模板)

<xsl:for-each select="key('belege-by-store', Store)">
<tr><td><xsl:value-of select="MemberFirstName" />
</td></tr>
</xsl:for-each>