XSLT通过元素匹配从XML复制元素



如果某些参数匹配,我需要在用其他XML的元素处理XML时替换一些元素。基本上是通知。xml是XML,我需要处理通知,仅在Notification-source.xml中替换/添加MSGTEXT,如果在Notification-source.xml中,请通知当前通知。如果没有匹配,则将通知保持不变。

notification.xml

<?xml version="1.0" encoding="UTF-8"?>
<Notifications>
  <BatchId>DOCATTR.BATCHID</BatchId>
  <Notification>
    <NotifId>1</NotifId>
    <Cid>DOCATTR.CID</Cid>
    <EmailNotification>
      <CcAddress>DOCATTR.EMAILCC</CcAddress>
      <CcName>DOCATTR.EMAILCCNAME</CcName>
      <BccAddress>DOCATTR.EMAILBCC</BccAddress>
      <SenderAddress>DOCATTR.SENDERADDRESS</SenderAddress>
      <SenderName>DOCATTR.SENDERNAME</SenderName>
      <MsgText>
      </MsgText>
      <Expiration>DOCATTR.EXPIRATION</Expiration>
      <Priority>DOCATTR.PRIORITYNC</Priority>
    </EmailNotification>
  </Notification>
</Notifications>

Notifications-source.xml

<?xml version="1.0" encoding="UTF-8"?>
<Notifications>
    <Notification>
        <NotifId>1</NotifId>
        <MsgText>
            <![CDATA[notif 1]]>
        </MsgText>
    </Notification>
    <Notification>
        <NotifId>2</NotifId>
        <MsgText>
            <![CDATA[notif 2]]>
        </MsgText>
    </Notification>
</Notifications>

这是我正在尝试的东西,但是它在其他地方复制了sgtext

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:strip-space elements="*"/>
  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="yes" cdata-section-elements="MsgText"/>
  <xsl:variable name="notifications" select="/"/>
  <xsl:variable name="notifications-source" select="document('notifications-source.xml')"/>
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="/">
    <Notifications>
      <xsl:for-each select="$notifications//Notification">
        <xsl:variable name="currentNotifId" select="./NotifId"/>
        <xsl:for-each select="$notifications-source//Notification">
          <xsl:variable name="remoteNotifId" select="./NotifId"/>
          <xsl:if test="$currentNotifId=$remoteNotifId">
            <xsl:copy>
              <xsl:copy-of select="./MsgText"/>
            </xsl:copy>
          </xsl:if>
        </xsl:for-each>
      </xsl:for-each>
    </Notifications>
  </xsl:template>
</xsl:stylesheet>

可以使用萨克森(Saxon(9.6.0-6为此,但是如果不适用,则可以是更新的。

所以我已经将模板更改为一个:

<xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="MsgText">
        <xsl:variable name="currentNotifId" select="../NotifId/text()"/>
        <xsl:choose>
            <xsl:when test="$notifications-source/Notifications/Notification/NotifId[text() = $currentNotifId]">
                <xsl:copy>
                    <xsl:copy-of select="$notifications-source/Notifications/Notification/NotifId[text() = $currentNotifId]/../MsgText"/>
                </xsl:copy>
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy>
                    <xsl:copy-of select="'test'"/>
                </xsl:copy>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

现在我只匹配msgText。但是目前我总是得到 <MsgText><![CDATA[test]]></MsgText>,所以我的gues我无法正确使用测试(选择(

路径 <xsl:variable name="currentNotifId" select="../NotifId/text()"/>不正确,应为 <xsl:variable name="currentNotifId" select="../../NotifId/text()"/>

您可能需要学习使用钥匙,然后简单地将条件放入匹配模式:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:param name="notifications-source">
<Notifications>
    <Notification>
        <NotifId>1</NotifId>
        <MsgText>
            <![CDATA[notif 1]]>
        </MsgText>
    </Notification>
    <Notification>
        <NotifId>2</NotifId>
        <MsgText>
            <![CDATA[notif 2]]>
        </MsgText>
    </Notification>
</Notifications>        
    </xsl:param>
    <xsl:key name="note-ref" match="Notification/MsgText" use="../NotifId"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="MsgText[key('note-ref', ../../NotifId, $notifications-source)]">  
       <xsl:copy-of select="key('note-ref', ../../NotifId, $notifications-source)"/>
    </xsl:template>
</xsl:transform>

在线http://xsltransform.net/93dehfx。