You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XSLT无法匹配XML节点:如何提取指定路径的Computer节点

问题描述

我正在编写基础XSLT程序,需要提取路径/Events/Event/System/Computer的节点,实现循环打印计算机名称(示例XML有2个Event节点,需打印两次)。但当前模板无法正确匹配目标节点,输出结构不符合预期,请求解决节点匹配问题。

我的XSLT样式表

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:template match="/">
  <html>
  <body>
  <h2>Event</h2>  
    <table>
        <tr>
        <xsl:apply-templates/>  
        </tr>
    </table>
  </body>
  </html>
</xsl:template>

<xsl:template match="Event">
    <td><xsl:apply-templates select="System"/> </td>
</xsl:template>

<xsl:template match="System">
    <xsl:apply-templates select="Computer"/> 
</xsl:template>


<xsl:template match="Computer">
  Computer: <span style="color:#ff0000">
  <xsl:value-of select="."/></span>
  <br />
</xsl:template>

</xsl:stylesheet>

XML示例

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Events>
    <Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'>
        <System>
            <Provider Name='Application Error'/>
            <EventID Qualifiers='0'>1000</EventID>
            <Version>0</Version>
            <Level>2</Level>
            <Task>100</Task>
            <Opcode>0</Opcode>
            <Keywords>0x80000000000000</Keywords>
            <TimeCreated SystemTime='2023-01-11T10:22:54.9821986Z'/>
            <EventRecordID>85280</EventRecordID>
            <Correlation/>
            <Execution ProcessID='0' ThreadID='0'/>
            <Channel>Application</Channel>
            <Computer>Peru-Desktop</Computer>
            <Security/>
        </System>
        <EventData>
            <Data>RuntimeBroker.exe</Data>
            <Data>10.0.19041.746</Data>
            <Data>5b78739c</Data>
            <Data>ntdll.dll</Data>
            <Data>10.0.19041.2130</Data>
            <Data>b5ced1c6</Data>
            <Data>c0000374</Data>
            <Data>00000000000ff6a9</Data>
            <Data>28c0</Data>
            <Data>01d9259e77eefd6c</Data>
            <Data>C:\Windows\System32\RuntimeBroker.exe</Data>
            <Data>C:\Windows\SYSTEM32\ntdll.dll</Data>
            <Data>66a01ef8-5dc9-4305-8670-d39ef7144aaf</Data>
            <Data>Microsoft.Windows.Search_1.14.7.19041_neutral_neutral_cw5n1h2txyewy</Data>
            <Data>runtimebroker07f4358a809ac99a64a67c1</Data>
        </EventData>
    </Event>
    <Event
        xmlns='http://schemas.microsoft.com/win/2004/08/events/event'>
        <System>
            <Provider Name='Application Error'/>
            <EventID Qualifiers='0'>1000</EventID>
            <Version>0</Version>
            <Level>2</Level>
            <Task>100</Task>
            <Opcode>0</Opcode>
            <Keywords>0x80000000000000</Keywords>
            <TimeCreated SystemTime='2023-01-11T05:17:35.3925442Z'/>
            <EventRecordID>85258</EventRecordID>
            <Correlation/>
            <Execution ProcessID='0' ThreadID='0'/>
            <Channel>Application</Channel>
            <Computer>Peru-Desktop</Computer>
            <Security/>
        </System>
        <EventData>
            <Data>ftnlsv.exe</Data>
            <Data>3.3.10.0</Data>
            <Data>5fa14984</Data>
            <Data>ntdll.dll</Data>
            <Data>10.0.19041.2130</Data>
            <Data>b5ced1c6</Data>
            <Data>c0000409</Data>
            <Data>000000000008c67f</Data>
            <Data>15bc</Data>
            <Data>01d925799d1bd691</Data>
            <Data>C:\Program Files\Common Files\VMware\DeviceRedirectionCommon\ftnlsv.exe</Data>
            <Data>C:\Windows\SYSTEM32\ntdll.dll</Data>
            <Data>96b01680-a7d7-4e54-b2a8-b350ed24498d</Data>
            <Data></Data>
            <Data></Data>
        </EventData>
    </Event>
</Events>

当前不符合预期的输出

<!DOCTYPE html>
<html>
   <body>
      <h2>Event</h2>
      <table>
         <tr><td>Computer: <span style="color:#ff0000">Peru-Desktop</span><br /></td></tr>
         <tr><td>Computer: <span style="color:#ff0000">Peru-Desktop</span><br /></td></tr>
</table></body></html>

问题原因

XML中的Event、System、Computer节点都属于命名空间http://schemas.microsoft.com/win/2004/08/events/event,但你的XSLT没有声明该命名空间,也没有使用命名空间前缀匹配节点,导致模板无法正确命中目标节点,当前输出是XSLT默认模板遍历节点后的结果,结构不符合预期。

解决方案

在XSLT中声明该命名空间的前缀,并在模板匹配和节点选择时使用前缀:

<?xml version="1.0" encoding="UTF-8"?>
<!-- 声明命名空间前缀 ev,绑定到XML中的事件命名空间 -->
<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ev="http://schemas.microsoft.com/win/2004/08/events/event">
<xsl:output method="html" indent="yes"/>
<xsl:template match="/">
  <html>
  <body>
  <h2>Event</h2>  
    <table>
        <tr>
        <!-- 明确选择Events下的ev:Event节点 -->
        <xsl:apply-templates select="Events/ev:Event"/>  
        </tr>
    </table>
  </body>
  </html>
</xsl:template>

<!-- 匹配带命名空间的Event节点 -->
<xsl:template match="ev:Event">
    <td><xsl:apply-templates select="ev:System"/> </td>
</xsl:template>

<!-- 匹配带命名空间的System节点 -->
<xsl:template match="ev:System">
    <xsl:apply-templates select="ev:Computer"/> 
</xsl:template>

<!-- 匹配带命名空间的Computer节点 -->
<xsl:template match="ev:Computer">
  Computer: <span style="color:#ff0000">
  <xsl:value-of select="."/></span>
  <br />
</xsl:template>

</xsl:stylesheet>

修正后输出

<!DOCTYPE html>
<html>
   <body>
      <h2>Event</h2>
      <table>
         <tr>
            <td>Computer: <span style="color:#ff0000">Peru-Desktop</span><br /></td>
            <td>Computer: <span style="color:#ff0000">Peru-Desktop</span><br /></td>
         </tr>
      </table>
   </body>
</html>

如果希望每个Event单独占一行(即每个Event对应一个<tr>),可以调整根模板中的结构:

<xsl:template match="/">
  <html>
  <body>
  <h2>Event</h2>  
    <table>
        <!-- 遍历每个ev:Event,为每个Event生成一行 -->
        <xsl:for-each select="Events/ev:Event">
        <tr>
            <xsl:apply-templates select="."/>  
        </tr>
        </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>

这样输出的每个计算机名称会单独占一行表格,符合常见的表格布局习惯。

内容的提问来源于stack exchange,提问作者Perumal Rm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 15:30:44