html - XLT 在 xml 标签之间交叉引用来决定应该添加什么类属性

标签 html css xml xslt

我有一个 xml 文件,它描述了代理和客户端之间的对话。双方都有一个 userId,在 newParty 标签中分配。

后续的消息和通知,引用这个userId。我希望在处理消息或通知时,使用 userId 完成查找,将字符串“Agent”或“Client”添加到生成的 HTML 的类属性中。

<?xml version="1.0"?>
<chatTranscript startAt="2016-10-06T09:16:40Z" sessionId="0001GaBYC53D000K">
<newParty userId="007957F616780001" timeShift="1" visibility="ALL" eventId="1">
    <userInfo personId="" userNick="John Doe" userType="CLIENT" protocolType="FLEX" timeZoneOffset="120"/>
    <userData>
        <item key="GMSServiceId">5954d184-f89d-4f44-8c0f-a772d458b353</item>
        <item key="IdentifyCreateContact">3</item>
        <item key="MediaType">chat</item><item key="TimeZone">120</item>
        <item key="_data_id">139-e9826bf5-c5a4-40e5-a729-2cbdb4776a43</item>
        <item key="firstName">John</item><item key="first_name">John</item>
        <item key="lastName">Doe</item>
        <item key="last_name">Doe</item>
        <item key="location_lat">37.8197</item>
        <item key="location_long">-122.4786</item>
        <item key="userDisplayName">John Doe</item>
    </userData>
</newParty>

<newParty userId="0079581AF56C0025" timeShift="20" visibility="ALL" eventId="2">
    <userInfo personId="1" userNick="allendei" userType="AGENT" protocolType="BASIC" timeZoneOffset="120"/>
</newParty>

<message userId="007957F616780001" timeShift="25" visibility="ALL" eventId="3">
    <msgText msgType="text" treatAs="NORMAL">This is message one.</msgText>
</message>

<message userId="0079581AF56C0025" timeShift="35" visibility="ALL" eventId="4">
    <msgText msgType="text" treatAs="NORMAL">This is message two.</msgText>
</message>

<notice userId="0079581AF56C0025" timeShift="40" visibility="ALL" eventId="5">
        <noticeText noticeType="USER_CUSTOM">This is notice one.</noticeText>
</notice>

<notice userId="007957F616780001" timeShift="58" visibility="ALL" eventId="6">
    <noticeText noticeType="USER_CUSTOM">This is notice two.</noticeText>
</notice>

<partyLeft userId="007957F616780001" timeShift="90" visibility="ALL" eventId="4" askerId="007957F616780001">
    <reason code="3">left due to disconnect</reason>
</partyLeft>

...我的 xlt 是:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:template match="/chatTranscript">
  <html>
    <header><xsl:value-of select="@sessionId" /></header>
    <xsl:apply-templates select="newParty" />
    <xsl:apply-templates select="message/msgText" />
    <xsl:apply-templates select="notice/noticeText" />
    <xsl:apply-templates select="partyLeft/reason" />
  </html>
</xsl:template>

<xsl:template match="newParty[userInfo/@userType='CLIENT']">
  <div class="Client" id="{@userId}">
    <label>Client: <xsl:value-of select="userInfo/@userNick" /></label>
  </div>
</xsl:template>

<xsl:template match="newParty[userInfo/@userType='AGENT']">
  <div class="Client" id="{@userId}">
    <label>Agent: <xsl:value-of select="userInfo/@userNick" /></label>
  </div>
</xsl:template> 

<xsl:template match="msgText">
  <div class="Messages" id="{../@eventId}">
    <label>Message: <xsl:value-of select="text()" /></label>
  </div>
</xsl:template>   

<xsl:template match="noticeText">
  <div class="Notices" id="{../@eventId}">
    <label>Notice: <xsl:value-of select="text()" /></label>
  </div>
</xsl:template>

<xsl:template match="reason">
  <div class="Notices" id="{../@eventId}">
    <label>Reason: <xsl:value-of select="text()" /></label>
  </div>
</xsl:template>

所需的输出如下 - 消息和通知的类属性(代理或客户端)通过顶部 newParties 中的用户 ID 查找。

<html>
<header>0001GaBYC53D000K</header>
<div class="Client" id="007957F616780001"><label>Client: John Doe</label></div>
<div class="Client" id="0079581AF56C0025"><label>Agent: allendei</label></div>
<div class="Messages,Client" id="3"><label>Message: This is message one.</label></div>
<div class="Messages,Agent" id="4"><label>Message: This is message two.</label></div>
<div class="Notices,Agent" id="5"><label>Notice: This is notice one.</label></div>
<div class="Notices,Client" id="6"><label>Notice: This is notice two.</label></div>
<div class="Notices,Client" id="4"><label>Reason: left due to disconnect</label></div>

最佳答案

XSLT 具有执行查找的内置机制。首先定义一个 key 作为:

<xsl:key name="party" match="newParty" use="@userId" />

然后使用它,如下例所示:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>

<xsl:key name="party" match="newParty" use="@userId" />

<xsl:template match="/chatTranscript">
    <html>
        <header>
            <xsl:value-of select="@sessionId" />
        </header>
        <xsl:apply-templates/>
    </html>
</xsl:template>

<xsl:template match="newParty[userInfo/@userType='CLIENT']">
    <div class="Client" id="{@userId}">
        <label>Client: <xsl:value-of select="userInfo/@userNick" /></label>
      </div>
</xsl:template>

<xsl:template match="newParty[userInfo/@userType='AGENT']">
    <div class="Client" id="{@userId}">
        <label>Agent: <xsl:value-of select="userInfo/@userNick" /></label>
    </div>
</xsl:template> 

<xsl:template match="message">
    <xsl:variable name="party-class">
        <xsl:call-template name="lookup-class"/>
    </xsl:variable>
    <div class="Messages,{$party-class}" id="{@eventId}">
        <label>Message: <xsl:value-of select="msgText" /></label>
    </div>
</xsl:template>   

<xsl:template match="notice">
    <xsl:variable name="party-class">
        <xsl:call-template name="lookup-class"/>
    </xsl:variable>
    <div class="Notices,{$party-class}" id="{@eventId}">
        <label>Notice: <xsl:value-of select="noticeText" /></label>
    </div>
</xsl:template>

<xsl:template match="partyLeft">
    <xsl:variable name="party-class">
        <xsl:call-template name="lookup-class"/>
    </xsl:variable>
    <div class="Notices,{$party-class}" id="{@eventId}">
        <label>Reason: <xsl:value-of select="reason" /></label>
    </div>
</xsl:template>

<xsl:template name="lookup-class">
    <xsl:variable name="party-type" select="key('party', @userId)/userInfo/@userType" />
    <xsl:choose>
        <xsl:when test="$party-type='CLIENT'">Client</xsl:when>
        <xsl:when test="$party-type='AGENT'">Agent</xsl:when>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>

请注意,输出不是有效的 HTML。

关于html - XLT 在 xml 标签之间交叉引用来决定应该添加什么类属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42107424/

相关文章:

html - 三个 float div 之间的间距相等

html - 如何在移动设备和平板电脑上将一列中的内容拆分为相邻的一列

jquery - 使用链接更改单独 div 的类

c# - XElement 保存问题

iphone - XML Parse 不显示内部带有 & 符号的元素

javascript - jquery中的自动点击按钮

javascript - 通过引用将 elementId 传递给 getElementById

html - Internet Explorer 11 X-UA-Compatible=IE8,框架的 UserAgent 错误

javascript - 除了需要指向的网站之外,是否可以托管 Javascript 文件?

c# - 使用 XmlReader 加载外部 dtd