使用 XSLT 时如何修复结束标记的对齐方式?

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

我仍在学习 XSLT,但我不知道如何解决这个问题:

</result>
创建的结束标签
xsltproc
仍然缩进,就好像它是元素的一部分一样;例如:

  <result>
      <channel>netgroup_home_hosts</channel>
      <value>0.006</value>
      <!--thresholds start--><LimitMaxWarning>1</LimitMaxWarning><LimitMaxError>2</LimitMaxError><!--thresholds end-->
      <!--range: min="0"-->
    </result>

但是我希望结束标签与开始标签对齐。 要么是我忘记了什么,要么是我没有正确使用 XSLT(额外的注释是一些调试遗留下来的)。

这是一个(简单的)示例输入:

<?xml version="1.0" encoding="utf-8"?>
<MonitoringOutput id="id-13951" version="0.1">
  <description>input</description>
  <exit_code>0</exit_code>
  <status_string>OK</status_string>
  <info_string>response_time(netgroup:home_hosts) is 0.006 (0)</info_string>
  <perf_string> netgroup_home_hosts=0.006;1;2;0</perf_string>
  <perf_data count="1">
    <sample label="netgroup_home_hosts">
      <label>netgroup_home_hosts</label>
      <value>0.006</value>
      <thresholds>
        <warn end="1"/>
        <crit end="2"/>
      </thresholds>
      <range min="0"/>
    </sample>
  </perf_data>
</MonitoringOutput>

这是创建的输出(注释是为了帮助我调试 XSLT):

<?xml version="1.0" encoding="UTF-8"?>
<!--MonitoringOutput v0.1 id=id-13951 (PRTG.xsl v0.0.0)-->
<prtg>
  <!--status_string=OK-->
  <!--success status!-->
  <!--perf_data:-->
  <!--Description: input-->
  <!--Exit Code: 0-->
  <text>OK</text>
  <!--Info String: response_time(netgroup:home_hosts) is 0.006 (0)-->
  <!--Perf String:  netgroup_home_hosts=0.006;1;2;0-->
  <result>
      <channel>netgroup_home_hosts</channel>
      <value>0.006</value>
      <!--thresholds start--><LimitMaxWarning>1</LimitMaxWarning><LimitMaxError\
>2</LimitMaxError><!--thresholds end-->
      <!--range: min="0"-->
    </result>
</prtg>

这就是 XSLT(可能过于复杂,但我想先把它做好,然后再优化):

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/MonitoringOutput[@version]">
  <xsl:comment><xsl:value-of select="name(.)"
  /> v<xsl:value-of select="@version" /> id=<xsl:value-of select="@id"
  /> (PRTG.xsl v0.0.0)</xsl:comment>
  <xsl:variable name="main.node" select="." />
  <prtg>
    <xsl:comment>status_string=<xsl:value-of
    select="$main.node/status_string" /> </xsl:comment>
    <xsl:choose>
      <xsl:when test="perf_data[@count &gt; 0]">
        <xsl:choose>
          <xsl:when test="$main.node/perf_data/crit_labels[@count &gt; 0]">
            <xsl:comment>critical status!</xsl:comment>
          </xsl:when>
          <xsl:when test="$main.node/perf_data/warn_labels[@count &gt; 0]">
            <xsl:comment>warnings status!</xsl:comment>
          </xsl:when>
          <xsl:otherwise>
            <xsl:comment>success status!</xsl:comment>
          </xsl:otherwise>
        </xsl:choose>
        <xsl:apply-templates select="$main.node/perf_data"/>
      </xsl:when>
      <xsl:otherwise>
        <error>1</error>
        <xsl:comment>(<xsl:value-of select="$main.node/exit_code"
        />)</xsl:comment>
        <text><xsl:value-of select="$main.node/info_string" /></text>
      </xsl:otherwise>
    </xsl:choose>
  </prtg>
</xsl:template>

<xsl:template match="perf_data[@count &gt; 0]">
  <!-- no parsing error -->
  <xsl:variable name="main.node" select=".." />
  <xsl:variable name="perf.node" select="." />
  <xsl:comment><xsl:value-of select="name(.)" />:</xsl:comment>
  <!-- HOW TO? -->
  <xsl:comment>Description: <xsl:value-of select="$main.node/description"
  /></xsl:comment>
  <xsl:comment>Exit Code: <xsl:value-of select="$main.node/exit_code"
  /></xsl:comment>
  <text><xsl:value-of select="$main.node/status_string" /></text>
  <xsl:comment>Info String: <xsl:value-of select="$main.node/info_string"
  /></xsl:comment>
  <xsl:comment>Perf String: <xsl:value-of select="$main.node/perf_string"
  /></xsl:comment>
  <xsl:apply-templates select="$perf.node/sample"/>
</xsl:template>

<xsl:template match="perf_data/sample[@label]">
  <result>
    <xsl:apply-templates />
    <xsl:variable name="is_crit" select="//crit_labels/name/text() = @label" />
    <xsl:variable name="is_warn" select="//warn_labels/name/text() = @label" />
    <xsl:choose>
      <xsl:when test="$is_crit">
        <warning>1</warning><xsl:comment>critical!</xsl:comment>
      </xsl:when>
      <xsl:when test="$is_warn">
        <warning>1</warning>
      </xsl:when>
    </xsl:choose>
  </result>
</xsl:template>

<xsl:template match="sample/label">
  <channel><xsl:value-of select="."/></channel>
</xsl:template>

<xsl:template match="sample/range[@*]">
  <xsl:for-each select="@*">
    <xsl:comment>range: <xsl:value-of select="name(.)" />="<xsl:value-of
    select="."/>"</xsl:comment>
  </xsl:for-each>
</xsl:template>

<xsl:template match="sample/unit">
  <CustomUnit><xsl:value-of select="."/></CustomUnit>
</xsl:template>

<xsl:template match="sample/value">
  <value><xsl:value-of select="."/></value>
</xsl:template>

<xsl:template match="sample/thresholds">
  <xsl:variable name="thresholds.node" select="." />
  <xsl:comment><xsl:value-of select="name(.)" /> start</xsl:comment>
  <xsl:apply-templates select="$thresholds.node/*"/>
  <xsl:comment><xsl:value-of select="name(.)" /> end</xsl:comment>
</xsl:template>

<xsl:template match="thresholds/crit[@*]">
  <xsl:for-each select="@*">
    <xsl:variable name="attr.name" select="name(.)" />
    <xsl:choose>
      <xsl:when test="$attr.name = 'start'">
        <LimitMinError><xsl:value-of select="." /></LimitMinError>
      </xsl:when>
      <xsl:when test="$attr.name = 'end'">
        <LimitMaxError><xsl:value-of select="." /></LimitMaxError>
      </xsl:when>
      <xsl:otherwise>
        <xsl:comment><xsl:value-of select="$attr.name" />="<xsl:value-of
        select="." />"</xsl:comment>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:for-each>
</xsl:template>

<xsl:template match="thresholds/warn[@*]">
  <xsl:for-each select="@*">
    <xsl:variable name="attr.name" select="name(.)" />
    <xsl:choose>
      <xsl:when test="$attr.name = 'start'">
        <LimitMinWarning><xsl:value-of select="." /></LimitMinWarning>
      </xsl:when>
      <xsl:when test="$attr.name = 'end'">
        <LimitMaxWarning><xsl:value-of select="." /></LimitMaxWarning>
      </xsl:when>
      <xsl:otherwise>
        <xsl:comment><xsl:value-of select="$attr.name" />="<xsl:value-of
        select="." />"</xsl:comment>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:for-each>
</xsl:template>

</xsl:stylesheet>
xml xslt indentation
1个回答
0
投票

FWIW,如果添加以下内容,缩进似乎是正确的:

<xsl:strip-space elements="*"/>

到样式表的顶层。显然,在某些时候,您将模板应用于输入的文本节点,这会导致仅空白节点被复制到输出。但我不打算在你的 137 行代码中寻找它。

© www.soinside.com 2019 - 2024. All rights reserved.