在更新之前确定元素值

Posted

技术标签:

【中文标题】在更新之前确定元素值【英文标题】:Determine element value before updating it 【发布时间】:2021-11-15 03:31:55 【问题描述】:

我希望我的 xslt 在更新之前检查字段的值。因此,当带有关键字“已批准”或“拒绝”的批准电子邮件发送到系统时,xslt 会相应地运行更新系统中的批准。如果批准已被批准或拒绝,则 xslt 不应再次更新它. 下面是更新字段的 xslt 的摘录:

    <!-- *********************** -->
    <!-- BEGIN: Define Variables -->
    <!-- *********************** -->
    
    <!-- find the profile link recid of the email sender -->
    <xsl:variable name="profilelink_recid">
    <!-- for each RelatedBusinessObject -->
      <xsl:for-each select="BusinessObjectList/BusinessObject/RelatedBusinessObjectList/RelatedBusinessObject/BusinessObject">
        <xsl:choose>
          <xsl:when test="@Name = 'Employee'">
            <xsl:for-each select="./FieldList/Field">
              <xsl:choose>
                <xsl:when test="@Name = 'RecId'">
                  <xsl:value-of select="."/>
                </xsl:when>
              </xsl:choose>
            </xsl:for-each>
          </xsl:when>
        </xsl:choose>
      </xsl:for-each>
    </xsl:variable>

    <!-- find the profile link category of the email sender -->
    <xsl:variable name="profilelink_cat">
      <!-- for each RelatedBusinessObject -->
      <xsl:for-each select="BusinessObjectList/BusinessObject/RelatedBusinessObjectList/RelatedBusinessObject/BusinessObject">
        <xsl:choose>
          <xsl:when test="@Name = 'Employee'">
            <xsl:value-of select="'Employee'"/>
          </xsl:when>
        </xsl:choose>
      </xsl:for-each>
    </xsl:variable>
    
    <!-- find subject and subjectID -->
    <xsl:variable name="emailSubject" select = "BusinessObjectList/BusinessObject/EmailMessage/Subject" />
    <xsl:variable name="emailSubjectID" select = "BusinessObjectList/BusinessObject/EmailMessage/SubjectID" />
    <xsl:variable name="emailBody" select = "BusinessObjectList/BusinessObject/EmailMessage/Body" />
    <xsl:variable name="EmailStatus" select="substring-before($emailBody,' ')"/>



        <xsl:for-each select="BusinessObjectList/BusinessObject">   
            <xsl:element name="BusinessObject">
                            <xsl:attribute name="Name"><xsl:value-of select="'FRS_ApprovalVoteTracking'"/></xsl:attribute>
                            <!-- Set Transaction as 'Update'.  It will try to update existing record using UniqueKey value, otherwise it will fail. -->
        <xsl:element name="Transaction">Update</xsl:element>
        <!--Unique Key List-->
        <xsl:element name="UniqueKeyList">
            <xsl:element name="UniqueKey">
                <xsl:element name="Field">
                    <xsl:attribute name="Name"><xsl:value-of select="'TrackingID'"/></xsl:attribute>
                </xsl:element>
            </xsl:element>
        </xsl:element>
                <FieldList>
                    <!-- Fields -->
                                <xsl:for-each select="EmailMessage/node()">
                                    <xsl:choose>
                                        <xsl:when test="name() = 'SubjectID'">
                                            <xsl:element name="Field">
                                                <xsl:attribute name="Name"><xsl:text>TrackingID</xsl:text></xsl:attribute>
                                                <xsl:attribute name="Type">System.Int32</xsl:attribute>
                                             <xsl:value-of select="."/> 
                                            </xsl:element>
                                        </xsl:when>
                                        <xsl:when test="name() = 'Body'">
                                            
                                            <xsl:element name="Field">
                                                <xsl:attribute name="Name"><xsl:text>Status</xsl:text></xsl:attribute>
                                            <xsl:choose>
                                            <xsl:when test="contains($EmailStatus,'Approved')">
                                                <xsl:text>Approved</xsl:text>
                                            </xsl:when>
                                            <xsl:when test="contains($EmailStatus,'Approve')">
                                                <xsl:text>Approved</xsl:text>
                                            </xsl:when>
                                            <xsl:when test="contains($EmailStatus,'Denied')">
                                                <xsl:text>Denied</xsl:text>
                                            </xsl:when>
                                            <xsl:when test="contains($EmailStatus,'Deny')">
                                                <xsl:text>Denied</xsl:text>
                                            </xsl:when>
                                            <xsl:when test="contains($EmailStatus,'approved')">
                                                <xsl:text>Approved</xsl:text>
                                            </xsl:when>
                                            <xsl:when test="contains($EmailStatus,'approve')">
                                                <xsl:text>Approved</xsl:text>
                                            </xsl:when>
                                            <xsl:when test="contains($EmailStatus,'denied')">
                                                <xsl:text>Denied</xsl:text>
                                            </xsl:when>
                                            <xsl:when test="contains($EmailStatus,'deny')">
                                                <xsl:text>Denied</xsl:text>
                                            </xsl:when>
                                            <xsl:otherwise>
                                            <xsl:text></xsl:text>
                                            </xsl:otherwise>
                                            </xsl:choose>
                                            </xsl:element> 
    
                                            <xsl:element name="Field">
                                                <xsl:attribute name="Name"><xsl:text>Reason</xsl:text></xsl:attribute>
                                            <xsl:choose>
                                            
                                            <xsl:when test="contains($EmailStatus,'Denied')">
                                                <xsl:text>Denied by Email</xsl:text>
                                            </xsl:when>
                                            <xsl:when test="contains($EmailStatus,'Deny')">
                                                <xsl:text>Denied by Email</xsl:text>
                                            </xsl:when>

                                            <xsl:otherwise>
                                            <xsl:text></xsl:text>
                                            <!-- <xsl:value-of select="$EmailStatus"/> -->
                                            </xsl:otherwise>
                                            </xsl:choose>
                                            </xsl:element>
                                            

                                        </xsl:when>
                                    </xsl:choose>
                                </xsl:for-each>
                            </FieldList>
                            <!-- Copy the RelatedBusinessObjectList element-->
                            <xsl:element name="RelatedBusinessObjectList">
                                <xsl:for-each select="RelatedBusinessObjectList">
                                    <xsl:copy-of select="node()"/>
                                </xsl:for-each>
                            </xsl:element>
                        </xsl:element>
                    </xsl:for-each> 
        <!--</xsl:element> -->
    <!--</xsl:element> -->
        </BusinessObjectList>
        </xsl:template>
</xsl:stylesheet>

所以 xslt 应该检查批准的当前状态,即如果它是“待定”,那么它应该更新,如果不是它不应该。

你知道怎么做吗?

【问题讨论】:

请在您的问题中发布minimal reproducible example,包括输入、您的尝试和预期输出作为代码,而不是外部链接中的图片。 投反对票,因为代码仅作为图像提供。 ***.com/help/someone-answers 【参考方案1】:

常见的方法是使用predicate 使用与您要修改的元素匹配的模板。例如:

XML

<Items>
    <Item>
        <ID>1</ID>
        <Name>Alpha</Name>
        <Color>Red</Color>
        <Status>Good</Status>
    </Item>
    <Item>
        <ID>2</ID>
        <Name>Bravo</Name>
        <Color>Green</Color>
        <Status>Pending</Status>
    </Item>
    <Item>
        <ID>3</ID>
        <Name>Charlie</Name>
        <Color>Blue</Color>
        <Status>Bad</Status>
    </Item>
    <Item>
        <ID>4</ID>
        <Name>Delta</Name>
        <Color>White</Color>
        <Status>Pending</Status>
    </Item>
</Items>

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="Status[.='Pending']">
    <xsl:copy>
        <xsl:text>Denied</xsl:text>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

结果

<?xml version="1.0" encoding="UTF-8"?>
<Items>
  <Item>
    <ID>1</ID>
    <Name>Alpha</Name>
    <Color>Red</Color>
    <Status>Good</Status>
  </Item>
  <Item>
    <ID>2</ID>
    <Name>Bravo</Name>
    <Color>Green</Color>
    <Status>Denied</Status>
  </Item>
  <Item>
    <ID>3</ID>
    <Name>Charlie</Name>
    <Color>Blue</Color>
    <Status>Bad</Status>
  </Item>
  <Item>
    <ID>4</ID>
    <Name>Delta</Name>
    <Color>White</Color>
    <Status>Denied</Status>
  </Item>
</Items>

【讨论】:

以上是关于在更新之前确定元素值的主要内容,如果未能解决你的问题,请参考以下文章

JS确定元素在数组中的索引值

如何根据属性值确定XML元素的子元素

是否可以确定何时使用 JavaScript 渲染了元素?

块级元素和内联元素的宽高是如何确定的

插入更新触发器如何确定是插入还是更新

更新查询中的 MongoTemplate 确定性顺序