通过 XSLT 根据条件修改 XML 元素值
Modifying the XML element value upon condiion by XSLT
我有 xml
<PhoneNumberDetails>
<PhoneNumber>
<Number>4162880001</Number>
<TimeStamp>2016-08-16T07:07:44-04:00</TimeStamp>
</PhoneNumber>
<PhoneNumber>
<Number>4162880002</Number>
<TimeStamp>2016-08-16T07:07:44-04:00</TimeStamp>
</PhoneNumber>
</PhoneNumberDetails>
这是 XSL 的输入。在此 XSL 中,我从存储在前一个 XSLT 中的上下文变量中检索一个 phone 数字,如果它与上面 xml 中的任何 phone 数字匹配,我需要将时间戳更新为新的当前时间戳。我需要这部分的帮助。
XSLT 代码:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dp="http://www.datapower.com/extensions" xmlns:date="http://exslt.org/dates-and-times" extension-element-prefixes="dp date" exclude-result-prefixes="dp">
<xsl:variable name="currentTimeStamp" select="date:date-time()"/>
<xsl:output method="xml"/>
<xsl:template match="PhoneNumberDetails">
<xsl:variable name="savedPhoneNum" select="dp:variable('var://context/name/phonenum')"/>
<xsl:choose>
<xsl:when test="/*[local-name()='PhoneNumberDetails']/*[local-name()='PhoneNumber']/*[local-name()='Number']=$savedPhoneNum">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="phonenumber"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="phonenumber" match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="PhoneNumberDetails">
<PhoneNumberDetails>
<xsl:apply-templates select="@* | *"/>
<PhoneNumber>
<Number>
<xsl:value-of select="dp:variable('var://context/name/phonenum')"/>
</Number>
<TimeStamp>
<xsl:value-of select="$currentTimeStamp"/>
</TimeStamp>
</PhoneNumber>
</PhoneNumberDetails>
</xsl:template>
</xsl:stylesheet>
如果 phone 数字与 XML 中的任何数字都不匹配,我需要向上面的 xml 添加一个新元素,这部分工作。例如
<PhoneNumber>
<Number>New number</Number>
<TimeStamp>Current TimeStamp</TimeStamp>
</PhoneNumber>
我建议你从这样的事情开始。不要使用 select phone 数字的绝对路径,从模板匹配的上下文节点使用它。
<xsl:template match="PhoneNumber">
<xsl:copy>
<xsl:copy-of select="Number"/>
<xsl:variable name="savedPhoneNum" select="dp:variable('var://context/name/phonenum')"/>
<TimeStamp>
<xsl:choose>
<xsl:when test="Number=$savedPhoneNum">
<xsl:value-of select="$currentTimeStamp"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="TimeStamp"/>
</xsl:otherwise>
</xsl:choose>
</TimeStamp>
</xsl:copy>
</xsl:template>
请注意,我假设您在输入的元素上没有(未显示的)名称空间 xml。如果是,请保留您的 *[local-name()=""] 构造,但随后必须将名称空间添加到 match="PhoneNumber" 和 TimeStamp 输出中。
为什么不能简单的做:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:dp="http://www.datapower.com/extensions"
xmlns:date="http://exslt.org/dates-and-times"
extension-element-prefixes="dp date">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="savedPhoneNum" select="dp:variable('var://context/name/phonenum')"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="TimeStamp[../Number=$savedPhoneNum]">
<xsl:copy>
<xsl:value-of select="date:date-time()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="PhoneNumberDetails[not(PhoneNumber/Number=$savedPhoneNum)]">
<xsl:copy>
<xsl:apply-templates/>
<PhoneNumber>
<Number>New number</Number>
<TimeStamp>Current TimeStamp</TimeStamp>
</PhoneNumber>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我有 xml
<PhoneNumberDetails>
<PhoneNumber>
<Number>4162880001</Number>
<TimeStamp>2016-08-16T07:07:44-04:00</TimeStamp>
</PhoneNumber>
<PhoneNumber>
<Number>4162880002</Number>
<TimeStamp>2016-08-16T07:07:44-04:00</TimeStamp>
</PhoneNumber>
</PhoneNumberDetails>
这是 XSL 的输入。在此 XSL 中,我从存储在前一个 XSLT 中的上下文变量中检索一个 phone 数字,如果它与上面 xml 中的任何 phone 数字匹配,我需要将时间戳更新为新的当前时间戳。我需要这部分的帮助。
XSLT 代码:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dp="http://www.datapower.com/extensions" xmlns:date="http://exslt.org/dates-and-times" extension-element-prefixes="dp date" exclude-result-prefixes="dp">
<xsl:variable name="currentTimeStamp" select="date:date-time()"/>
<xsl:output method="xml"/>
<xsl:template match="PhoneNumberDetails">
<xsl:variable name="savedPhoneNum" select="dp:variable('var://context/name/phonenum')"/>
<xsl:choose>
<xsl:when test="/*[local-name()='PhoneNumberDetails']/*[local-name()='PhoneNumber']/*[local-name()='Number']=$savedPhoneNum">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="phonenumber"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="phonenumber" match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="PhoneNumberDetails">
<PhoneNumberDetails>
<xsl:apply-templates select="@* | *"/>
<PhoneNumber>
<Number>
<xsl:value-of select="dp:variable('var://context/name/phonenum')"/>
</Number>
<TimeStamp>
<xsl:value-of select="$currentTimeStamp"/>
</TimeStamp>
</PhoneNumber>
</PhoneNumberDetails>
</xsl:template>
</xsl:stylesheet>
如果 phone 数字与 XML 中的任何数字都不匹配,我需要向上面的 xml 添加一个新元素,这部分工作。例如
<PhoneNumber>
<Number>New number</Number>
<TimeStamp>Current TimeStamp</TimeStamp>
</PhoneNumber>
我建议你从这样的事情开始。不要使用 select phone 数字的绝对路径,从模板匹配的上下文节点使用它。
<xsl:template match="PhoneNumber">
<xsl:copy>
<xsl:copy-of select="Number"/>
<xsl:variable name="savedPhoneNum" select="dp:variable('var://context/name/phonenum')"/>
<TimeStamp>
<xsl:choose>
<xsl:when test="Number=$savedPhoneNum">
<xsl:value-of select="$currentTimeStamp"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="TimeStamp"/>
</xsl:otherwise>
</xsl:choose>
</TimeStamp>
</xsl:copy>
</xsl:template>
请注意,我假设您在输入的元素上没有(未显示的)名称空间 xml。如果是,请保留您的 *[local-name()=""] 构造,但随后必须将名称空间添加到 match="PhoneNumber" 和 TimeStamp 输出中。
为什么不能简单的做:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:dp="http://www.datapower.com/extensions"
xmlns:date="http://exslt.org/dates-and-times"
extension-element-prefixes="dp date">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="savedPhoneNum" select="dp:variable('var://context/name/phonenum')"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="TimeStamp[../Number=$savedPhoneNum]">
<xsl:copy>
<xsl:value-of select="date:date-time()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="PhoneNumberDetails[not(PhoneNumber/Number=$savedPhoneNum)]">
<xsl:copy>
<xsl:apply-templates/>
<PhoneNumber>
<Number>New number</Number>
<TimeStamp>Current TimeStamp</TimeStamp>
</PhoneNumber>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>