提问人:U. Windl 提问时间:10/4/2023 最后编辑:U. Windl 更新时间:10/6/2023 访问量:40
如何将信息从内部元素传播到外部元素?
How to propagate information from inner elements to outer element?
问:
对于XSLT:当缺少特定的内部子元素时如何跳过元素?中描述的内容模型,我有一个新问题:
我需要在外部级别创建不同的输出,具体取决于匹配内部级别。 例如,请考虑以下部分:
<!-- ... -->
<perf_data count="2">
<sample label="in">
<label>in</label>
<range min="0"/>
</sample>
<sample label="out">
<label>out</label>
<range min="0"/>
</sample>
</perf_data>
<!-- ... -->
有两个元素,但其中没有一个元素包含元素,这实际上使它们变得无用。sample
value
我写了一条规则来“冗长地忽略”这些元素,如下所示:
<xsl:template match="perf_data/sample[@label and not(value)]">
<xsl:comment>Skipped incomplete sample "<xsl:value-of select="label"
/>"</xsl:comment>
</xsl:template>
但是,我还需要的是,如果忽略所有示例
元素,那么我必须在输出(也许)上创建一个额外的外部元素,否则在“级别”上。<Error>1</Error>
<Error>0</Error>
perf_data
但是我不知道如何实现它,特别是因为您不能在变量中具有计数器;否则我会暗示计算有效的 s 并检查计数。
我该怎么做?sample
另请参阅 XSLT:选择一个节点,其中其子节点的非子节点具有给定的属性(即 ¬∃ (∄))。
示例输入
下面是两个输入示例,一个好的,一个坏的:
不良样品
<?xml version="1.0" encoding="utf-8"?>
<MonitoringOutput id="id-3150" version="0.2">
<description>snmp_netif-1.out</description>
<exit_code>0</exit_code>
<status_string>Previous state not found, U octets/s in [delta 0s], U octets/s out [delta 0s]</status_string>
<perf_string> in=U;;;0 out=U;;;0</perf_string>
<perf_data count="2">
<sample label="in">
<label>in</label>
<range min="0"/>
</sample>
<sample label="out">
<label>out</label>
<range min="0"/>
</sample>
</perf_data>
</MonitoringOutput>
好样品
<?xml version="1.0" encoding="utf-8"?>
<MonitoringOutput id="id-3160" version="0.2">
<description>snmp_netif-2.out</description>
<exit_code>0</exit_code>
<status_string>bond0</status_string>
<info_string>1560.23 octets/s in [delta 10s], 350.921 octets/s out [delta 10s]</info_string>
<perf_string> in=1560.23B;;;0 out=350.921B;;;0</perf_string>
<perf_data count="2">
<sample label="in">
<label>in</label>
<value unit="B">1560.23</value>
<unit>B</unit>
<range min="0"/>
</sample>
<sample label="out">
<label>out</label>
<value unit="B">350.921</value>
<unit>B</unit>
<range min="0"/>
</sample>
</perf_data>
</MonitoringOutput>
因此,所有 s 中的缺失应该“向上”传播到处理时,应将其视为空或不存在。<value>
<sample>
<perf_data>
答:
1赞
Siebe Jongebloed
10/6/2023
#1
Do you mean something like this
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/Document[not(perf_data/sample[not(@label and not(value))])]">
<Error>1</Error>
</xsl:template>
<xsl:template match="perf_data[sample[@label and not(value)]]">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<Error>0</Error>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
如果我们有这个 xml:
<Document>
<perf_data count="2">
<sample label="in">
<label>in</label>
<range min="0"/>
</sample>
<sample label="out">
<label>out</label>
<range min="0"/>
</sample>
</perf_data>
<perf_data count="2">
<sample label="in">
<label>in</label>
<range min="0"/>
</sample>
<sample label="out">
<label>out</label>
<range min="0"/>
<value/> <!-- value-element present -->
</sample>
</perf_data>
</Document>
此 xslt 将给出此结果
<Document>
<perf_data count="2">
<sample label="in">
<label>in</label>
<range min="0"/>
</sample>
<sample label="out">
<label>out</label>
<range min="0"/>
</sample>
<Error>0</Error>
</perf_data>
<perf_data count="2">
<sample label="in">
<label>in</label>
<range min="0"/>
</sample>
<sample label="out">
<label>out</label>
<range min="0"/>
<value/>
</sample>
<Error>0</Error>
</perf_data>
</Document>
如果我们有这个 xml:
<Document>
<perf_data count="2">
<sample label="in">
<label>in</label>
<range min="0"/>
</sample>
<sample label="out">
<label>out</label>
<range min="0"/>
</sample>
</perf_data>
<perf_data count="2">
<sample label="in">
<label>in</label>
<range min="0"/>
</sample>
<sample label="out">
<label>out</label>
<range min="0"/>
</sample>
</perf_data>
</Document>
它将给出以下结果:
<Error>1</Error>
评论
0赞
U. Windl
10/6/2023
我明白了,你的XSL技能比我好得多。实际上,我已经制定了一个稍微复杂一些的解决方案,但为了完整起见,我也将在这里提供它。
0赞
U. Windl
10/6/2023
不幸的是,对于我刚刚添加到问题中的坏例子,您的 XSLT 无法正常工作:我得到输出和内部。perf_data
<Error>0</Error>
0赞
U. Windl
10/6/2023
#2
我设法处理了这样的情况(感谢 michael-hor257k 给出的提示):
<xsl:template match="/MonitoringOutput[@version]">
<xsl:variable name="main.node" select="." />
<Prtg>
<!-- ... -->
<xsl:choose>
<xsl:when test="count($main.node/perf_data/sample[value]) = 0">
<xsl:comment>(no valid sample)</xsl:comment>
<Error>1</Error>
<!-- ... -->
</xsl:when>
<xsl:when test="perf_data[@count > 0]">
<xsl:comment>(non-empty perf_data)</xsl:comment>
<xsl:apply-templates select="$main.node/perf_data"/>
<!-- ... -->
</xsl:when>
<xsl:otherwise>
<xsl:comment>(empty perf_data)</xsl:comment>
<Error>1</Error>
<!-- ... -->
</xsl:otherwise>
</xsl:choose>
</Prtg>
</xsl:template>
评论
perf_data
sample
count()