【发布时间】:2017-11-30 10:01:03
【问题描述】:
如果某些参数匹配,我需要将处理 xml 中的某些元素替换为其他 xml 中的元素。基本上,notifications.xml 是 xml,我需要在其中处理通知,并且只有在 notification-source.xml 中的 NotifId 等于当前通知的 NotifId 时才用来自 notification-source.xml 的 MsgText 替换/添加 MsgText。如果没有匹配,则保持通知不变。
notifications.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>
这是我正在尝试的,但它正在将 msgText 复制到其他地方
<?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-he 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> 所以我猜我没有正确使用测试(选择)
【问题讨论】:
-
这个问题与stackoverflow.com/questions/44762709/… 不同吗?或者你为什么要问一个新问题?如果您希望我们了解您想要实现的目标,那么您应该向我们展示您发布的输入示例所需的结果,因为您的代码到目前为止还没有实现它。
-
因为我无法删除旧问题,所以我要问一个新问题(我希望)有更好的描述。
标签: xml xslt transformation saxon