【发布时间】:2017-10-09 15:32:01
【问题描述】:
我需要测试一个 xml 消息,如果它包含任何 modtime 大于某个值的对象。目前我使用一个样式表明确列出要测试的 xml 中的每个路径。
<xsl:if test="(translate(proot_modtime,'-T:Z','')>=translate('2017-09-30T00:00:45','-T:Z',''))
or (translate(a/a/pa_modtime,'-T:Z','')>=translate('2017-09-30T00:00:45','-T:Z',''))
or (translate(b/b/pb_modtime,'-T:Z','')>=translate('2017-09-30T00:00:45','-T:Z',''))
">
<xsl:copy>
<xsl:copy-of select="./@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:if>
当 xml 消息更改时,我倾向于忘记更新样式表。这就是为什么我正在寻找更通用的选择。这会查找所有包含单词 modtime 的子节点,并且应该检查所有子节点。我尝试使用 XPath 表达式,匹配所有 Modtime-Nodes
<xsl:if test="(translate(//*[ends-with(name(), '_modtime')],'-T:Z','')>=translate('2017-09-30T00:00:45','-T:Z',''))"> <xsl:copy>
<xsl:copy-of select="./@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:if>
不幸的是,上面的代码 sn-p,只会测试第一个 *_modtime 节点而忽略所有其他节点。其实我想测试所有
有人有什么想法,在 XSL 中描述以下内容: "如果 XML 树中的任何 modtime 节点包含大于 x 的值,则复制整个 xml"
示例 XML:
<root>
<proot_modtime>2017-09-28T00:00:00</proot_modtime>
<a>
<a>
<pa_modtime>2017-10-01T16:15:15</pa_modtime>
</a>
</a>
<b>
<b>
<pb_modtime>2017-09-30T00:00:00</pb_modtime>
</b>
</b>
</root>
完整的 XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" omit-xml-declaration="yes" indent="no"/>
<xsl:template match="root">
<xsl:if test="(translate(//*[ends-with(name(), '_modtime')],'-T:Z','')>=translate('2017-09-30T00:00:45','-T:Z',''))">
<xsl:copy>
<xsl:copy-of select="./@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:if>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="./@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
【问题讨论】:
-
复制整个 xml?整个 XML 文档还是只是节点标记?如果不符合标准会怎样?
-
xsl 应复制整个消息或将其转换为空字符串。因为 modtime
-
再次,message 是什么意思?整个 XML 文档?所有
<root>? -
如果您被限制使用 XSLT 1.0,请这样说。在当前版本的语言中,操作日期和时间要容易得多。
-
@Parfait,是的,整个 xml 文档