如何将信息从内部元素传播到外部元素?

问题描述 投票:0回答:1

对于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>

但是我还需要的是如果all

sample
元素被忽略,那么我必须在输出上创建一个额外的外部元素(也许
<Error>1</Error>
),否则
<Error>0</Error>
在“
perf_data
”级别”.

但是我不知道如何实现它,特别是因为变量中不能有计数器;否则我会暗示计算有效的

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>

因此,所有

<value>
中不存在
<sample>
的情况应“向上”传播到
<perf_data>
的处理,然后应将其视为空或不存在。

xslt match
1个回答
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>
© www.soinside.com 2019 - 2024. All rights reserved.