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

XSL 1.0如何将XML嵌套节点值存入变量并正常调用

问题描述

我使用XSL 1.0,需要深层遍历XML节点序列提取值,以下是我的XML示例:

<?xml version="1.0" encoding="UTF-8"?>
<mpcconfiguration>
   <lineitem id="0" seriesid="series1" modelid="model1">
      <seriesdesc>Series #1</seriesdesc>
      <modeldesc>Model #1</modeldesc>
      <category id="Mstr_Information">
         <option id="Mstr_Information">
            <unitprice>0</unitprice>
            <property id="ExtPrice">0</property>
            <property id="Mstr_ModelSortOrder">3</property>
         </option>
      </category>
   </lineitem>
   <lineitem id="1" seriesid="series2" modelid="model2">
      <seriesdesc>Series #2</seriesdesc>
      <modeldesc>Model #2</modeldesc>
      <category id="Mstr_Information">
         <option id="Mstr_Information">
            <description>descr1</description>
            <unitprice>0</unitprice>
            <property id="ExtPrice">0</property>
            <property id="Mstr_ModelSortOrder">1</property>
         </option>
      </category>
   </lineitem>
   <lineitem id="2" seriesid="series3" modelid="model3">
      <seriesdesc>Series #3</seriesdesc>
      <modeldesc>Model #3</modeldesc>
      <category id="Mstr_Information">
         <option id="Mstr_Information">
            <description>descr1</description>
            <unitprice>0</unitprice>
            <property id="ExtPrice">0</property>
            <property id="Mstr_ModelSortOrder">2</property>
         </option>
      </category>
   </lineitem>
</mpcconfiguration>

我要获取每个<lineitem>内目标值的选择器如下:

category[@id='Mstr_Information']/option[@id='Mstr_Information']/property[@id='Mstr_ModelSortOrder']

我已确认上述选择器正确,已在XSL顶部的排序逻辑中成功使用。我尝试按如下方式将该值提取到变量中:

<xsl:variable name="modelSortOrder">
    <xsl:value-of select="category[@id='Mstr_Information']/option[@id='Mstr_Information']/property[@id='Mstr_ModelSortOrder']"/>
</xsl:variable>

后续我按如下方式调用该变量:

<span style="width: 50px">
   <b>Model Sort Order: </b>
</span>
<xsl:value-of select="$modelSortOrder" />

但运行失败,$modelSortOrder最终返回空字符串。以下是我当前精简后的可运行版本XSL:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ms="urn:schemas-microsoft-com:xslt">
   
   <xsl:template match="mpcconfiguration">
      <xsl:copy>
         <xsl:apply-templates select="@*" />
         <xsl:apply-templates select="lineitem">
            <xsl:sort select="category[@id='Mstr_Information']/option[@id='Mstr_Information']/property[@id='Mstr_ModelSortOrder']" data-type="number" />
         </xsl:apply-templates>
      </xsl:copy>
   </xsl:template>
   
   <xsl:template match="lineitem">
      <xsl:variable name="lineItemId">
         <xsl:value-of select="@id"/>
      </xsl:variable>
      <xsl:variable name="seriesId">
         <xsl:value-of select="@seriesid"/>
      </xsl:variable>
      <xsl:variable name="modelId">
         <xsl:value-of select="@modelid"/>
      </xsl:variable>
      
      <xsl:variable name="modelSortOrder">
         <xsl:value-of select="category[@id='Mstr_Information']/option[@id='Mstr_Information']/property[@id='Mstr_ModelSortOrder']"/>
      </xsl:variable>

      <div class="xRgn">
         <table class="xInner">
            <tr>
               <td class="col">
                  <xsl:element name="div">
                     <div style="float:left; margin:3px">
                        
                      <span style="width: 50px">
                         <b>Series: </b>
                      </span>
                      <xsl:choose>
                         <xsl:when test="not(seriesdesc)">
                            <xsl:value-of select="@seriesid" />
                         </xsl:when>
                         <xsl:otherwise>
                            <xsl:value-of select="seriesdesc" />
                         </xsl:otherwise>
                      </xsl:choose>
                      <br />
                      <span style="width: 50px">
                         <b>Model: </b>
                      </span>
                      <xsl:choose>
                         <xsl:when test="not(modeldesc)">
                            <xsl:value-of select="@modelid" />
                         </xsl:when>
                         <xsl:otherwise>
                            <xsl:value-of select="modeldesc" />
                         </xsl:otherwise>
                      </xsl:choose>
                      <br />
                      <span style="width: 50px">
                         <b>Model Sort Order: </b>
                      </span>
                      <xsl:value-of select="$modelSortOrder" />
                      <br />
                       
                     </div>
                  </xsl:element>
               </td>
            </tr>
         </table>
      </div>
   </xsl:template>
</xsl:stylesheet>

上述代码在我的.NET环境中运行基本正常(仅变量为空问题),排序逻辑、<lineitem>节点遍历、各节点对应的HTML生成结果均正确,寻求该变量空值问题的解决方法。


解决方案

该问题由XSLT 1.0的结果树片段(RTF)特性导致,.NET自带的XSLT处理器对这种写法兼容性较差:
你当前的变量定义方式是在变量标签内部嵌套<xsl:value-of>,这种写法会生成一个结果树片段,而非直接的字符串值,部分场景下读取时会返回空。

直接把变量的赋值方式改成用select属性即可解决:

<xsl:variable name="modelSortOrder" select="string(category[@id='Mstr_Information']/option[@id='Mstr_Information']/property[@id='Mstr_ModelSortOrder'])" />

这里加string()函数是为了显式把节点转为字符串值,进一步避免取值异常。

如果需要排查路径问题,可以临时在输出变量的位置加入调试代码,逐层验证节点是否存在:

<!-- 验证category节点是否存在 -->
<xsl:value-of select="count(category[@id='Mstr_Information'])" />
<!-- 验证option节点是否存在 -->
<xsl:value-of select="count(category[@id='Mstr_Information']/option[@id='Mstr_Information'])" />
<!-- 验证property节点是否存在 -->
<xsl:value-of select="count(category[@id='Mstr_Information']/option[@id='Mstr_Information']/property[@id='Mstr_ModelSortOrder'])" />

你已经确认排序逻辑正常,说明路径完全正确,只需要修改变量定义方式即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 11:09:02