gpt4 book ai didi

XSLT 格式化以删除空列(和标题)

转载 作者:行者123 更新时间:2023-12-01 02:52:28 24 4
gpt4 key购买 nike

我有一个数据库字段,我正在从中提取 xml。该字段包含来自多个 XML 提要的内容,我需要其中的两个。我在页面上显示 XML 并使用 XSLT 对其进行格式化。

我的问题是 DB 中每条消息最多可能有 40 个元素,其中我正在寻找大约 30 个。但是,并非所有消息都包含全部 30 个。如果没有,我需要帮助弄清楚如何删除列要显示的数据。

如果我可以使用 XSLT,那就太好了,如果它是 JavaScript(Jquery),那也很好。一次永远不会超过一行和一个标题。

这是 XML 的示例

<MessageToUser>
<Name>Bob</Name>
<MessageType>Text Message</MessageType>
<MessageID>121223</MessageID>
<ResponseTo />
<Message>Call Me Please </Message>
<OfficePhone>555-555-1212</OfficePhone>
<CellPhone>555-555-5555</CellPhone>
</MessageToUser>

这是我正在使用的 XSL
<xsl:template match="/">
<html>
<head>
<style type="text/css">
.Header{min-width: 100px;background-color:#9acddd;}
</style>
</head>
<body>
<table border="1">
<tr>
<th class="Header">Name</th>
<th class="Header">Message</th>
<th class="Header">Cell Phone</th>
<th class="Header">Office Phone</th>
<th class="Header">Message Type</th>
<th class="Header">Message Time</th>
<th class="Header">Message ID</th>
</tr>
<xsl:for-each select="MessageFromUser">
<tr>
<td><xsl:value-of select="Name" /></td>
<td><xsl:value-of select="Message" /></td>
<td><xsl:value-of select="CellPhone" /></td>
<td><xsl:value-of select="OfficePhone" /></td>
<td><xsl:value-of select="MessageType" /></td>
<td><xsl:value-of select="MessageTime" /></td>
<td><xsl:value-of select="MessageID" /></td>
</tr>
</xsl:for-each>
<xsl:for-each select="MessageToUser">
<tr>
<td><xsl:value-of select="Name" /></td>
<td><xsl:value-of select="Message" /></td>
<td><xsl:value-of select="CellPhone" /></td>
<td><xsl:value-of select="OfficePhone" /></td>
<td><xsl:value-of select="MessageType" /></td>
<td><xsl:value-of select="MessageTime" /></td>
<td><xsl:value-of select="MessageID" /></td>
</tr>
</xsl:for-each>
</table>
</body>



使用此 XML MessageTime 为空,应删除该列。

在此先感谢您的帮助。

最佳答案

这种转变:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my" exclude-result-prefixes="my" >
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<my:Layout>
<html>
<head>
<style type="text/css">
.Header{min-width: 100px;background-color:#9acddd;}
</style>
</head>
<body>
<table border="1">
<tr>
<header name="Name">Name</header>
<header name="Message">Message</header>
<header name="CellPhone">Cell Phone</header>
<header name="OfficePhone">Office Phone</header>
<header name="MessageType">Message Type</header>
<header name="MessageTime">Message Time</header>
<header name="MessageID">Message ID</header>
</tr>
<every select="MessageFromUser">
<tr>
<Name/>
<Message/>
<CellPhone/>
<OfficePhone/>
<MessageType/>
<MessageTime/>
<MessageID/>
</tr>
</every>
<every select="MessageToUser">
<tr>
<Name/>
<Message/>
<CellPhone/>
<OfficePhone/>
<MessageType/>
<MessageTime/>
<MessageID/>
</tr>
</every>
</table>
</body>
</html>
</my:Layout>

<xsl:variable name="vLayout" select="document('')/*/my:Layout/*"/>
<xsl:variable name="vDoc" select="/"/>

<xsl:template match="node()|@*">
<xsl:param name="pContextNode"/>
<xsl:copy>
<xsl:apply-templates select="node()|@*">
<xsl:with-param name="pContextNode" select="$pContextNode"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>

<xsl:template match=
"Name|Message|CellPhone|OfficePhone|MessageType|MessageTime|MessageID">
<xsl:param name="pContextNode"/>

<xsl:if test="not($vDoc/*/*[not(*[name()=name(current())])])">
<td><xsl:value-of select="$pContextNode/*[name()=name(current())]"/></td>
</xsl:if>

</xsl:template>

<xsl:template match="/*">
<xsl:apply-templates select="$vLayout"/>
</xsl:template>

<xsl:template match="header">
<xsl:if test="not($vDoc/*/*[not(*[name()=current()/@name])])">
<th class="Header"><xsl:value-of select="."/></th>
</xsl:if>
</xsl:template>

<xsl:template match="every">
<xsl:variable name="vLayoutTop" select="."/>
<xsl:for-each select="$vDoc/*/*[name()=current()/@select]">
<xsl:apply-templates select="$vLayoutTop/*">
<xsl:with-param name="pContextNode" select="."/>
</xsl:apply-templates>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

应用于此 XML 文档时 (提供的一个并添加了 MessageFromUser ):
<Messages>
<MessageFromUser>
<Name>Bob</Name>
<MessageType>Text Message</MessageType>
<MessageID>121223</MessageID>
<ResponseTo />
<Message>Call Me Please </Message>
<OfficePhone>555-555-1212</OfficePhone>
<CellPhone>555-555-5555</CellPhone>
</MessageFromUser>
<MessageToUser>
<Name>Bob</Name>
<MessageType>Text Message</MessageType>
<MessageID>121223</MessageID>
<ResponseTo />
<Message>Call Me Please </Message>
<OfficePhone>555-555-1212</OfficePhone>
<CellPhone>555-555-5555</CellPhone>
</MessageToUser>
</Messages>

产生想要的输出 ,其中不显示空列 1MessageTime`:
<html xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my="my:my">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css">
.Header{min-width: 100px;background-color:#9acddd;}
</style></head>
<body>
<table border="1">
<tr>
<th class="Header">Name</th>
<th class="Header">Message</th>
<th class="Header">Cell Phone</th>
<th class="Header">Office Phone</th>
<th class="Header">Message Type</th>
<th class="Header">Message ID</th>
</tr>
<tr>
<td>Bob</td>
<td>Call Me Please </td>
<td>555-555-5555</td>
<td>555-555-1212</td>
<td>Text Message</td>
<td>121223</td>
</tr>
<tr>
<td>Bob</td>
<td>Call Me Please </td>
<td>555-555-5555</td>
<td>555-555-1212</td>
<td>Text Message</td>
<td>121223</td>
</tr>
</table>
</body>
</html>

请注意 :
  • 更好的设计 (填空)使用 ,将代码和演示文稿分开。 这是最基本和最强大的 XSLT 设计(填空)模式之一 .
  • 这种设计允许将相同的代码用于不同的布局 (作为参数传递)以产生完全不同的结果。
  • 身份规则“按原样”复制布局的所有非可变节点 .
  • 我们仅覆盖布局的“可变”部分的标识规则 .
  • 辅助元件every指定应执行迭代处理 .
  • 在实际应用中 <my:Layout>元素将作为单独的 XML 文档驻留 在一个单独的文件中,在这种情况下必须替换 document('')/*document('theFileURI') .将此文件 URI 作为参数传递给 XSLT 转换时,可获得最大的通用性。
  • 测试条件以仅处理至少在一条记录中至少出现一次的字段/列 是(对于标题):
  • not($vDoc/*/*[not(*[name()=current()/@name])])
    细胞的类似条件是:
    not($vDoc/*/*[not(*[name()=name(current())])])

    关于XSLT 格式化以删除空列(和标题),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4441205/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com