此处不能使用axis step child::element('':PRODUCT_LIST):上下文项是原子值

Axis step child::element('':PRODUCT_LIST) cannot be used here: the context item is an atomic value

在此先感谢您的支持。

我有以下 xml 和 xslt

<SUBSCRIBER>
    <PRODUCT_LIST>
        <PRODUCT_INFO>
            <ID>BA3</ID>
            <PRODUCT_TYPE>Chargeable Bonus Product</PRODUCT_TYPE>
            <NSN1>34178</NSN1>
            <NSN2>2015-02-18 23:59:59</NSN2>
            <OFFER>1104</OFFER>
            <DA_UNIT>time</DA_UNIT>
            <UA>1003</UA>
        </PRODUCT_INFO>
        <PRODUCT_INFO>
            <ID>SID15</ID>
            <PRODUCT_TYPE>Rate Cutter</PRODUCT_TYPE>
            <NSN1>2015-12-23</NSN1>
            <OFFER>1215</OFFER>
        </PRODUCT_INFO>
        <PRODUCT_INFO>
            <ID>UseRs325GetRs25</ID>
            <PRODUCT_TYPE>Usage Subscription- Traffic</PRODUCT_TYPE>
            <NSN1>0</NSN1>
            <NSN2>2015-02-15</NSN2>
            <NSN3>2015-02-05</NSN3>
            <NSN4>2015-02-15 14:01:33</NSN4>
            <OFFER>1250</OFFER>
            <UA>1095</UA>
            <UA2>1096</UA2>
            <THRESHOLD>325</THRESHOLD>
            <UA_INTERVAL>10</UA_INTERVAL>
        </PRODUCT_INFO>
    </PRODUCT_LIST>
</SUBSCRIBER>

XSLT:

<xsl:template match="SUBSCRIBER">

    <xsl:variable name="PRODUCT_TYPE" select="PRODUCT_LIST/PRODUCT_INFO[(PRODUCT_TYPE eq 'Chargeable Bonus Product') or (PRODUCT_TYPE eq 'Home Zone') or (PRODUCT_TYPE eq 'Usage Subscription- Traffic') or (PRODUCT_TYPE eq 'Telescopic Charging') or (PRODUCT_TYPE eq 'Usage Subscription- Recharge')]/PRODUCT_TYPE"/>
    <xsl:for-each select="1 to count($PRODUCT_TYPE)">
        <xsl:variable name="index" select="."/>
        <xsl:variable name="product_name" select="$PRODUCT_TYPE[$index]"/>
        <xsl:value-of select="PRODUCT_LIST/PRODUCT_INFO[(PRODUCT_TYPE eq $product_name)]/UA"/>
    </xsl:for-each>

</xsl:template>

我遇到以下异常,

说明:此处不能使用轴步child::element('':PRODUCT_LIST):上下文项是原子值

请指教。

错误消息说明了一切 - 当您在 1 to count($PRODUCT_TYPE) 的 for-each 中时,上下文项 (.) 是一个数字而不是一个节点,因此您不能使用value-of 中的相对 XPath。您需要将 for-each 外部的上下文项保存在另一个变量中,然后使用相对于该变量的路径:

<xsl:variable name="dot" select="."/><!-- . here is the SUBSCRIBER -->
<xsl:for-each select="1 to count($PRODUCT_TYPE)">
    <xsl:variable name="index" select="."/><!-- . here is the number -->
    <xsl:variable name="product_name" select="$PRODUCT_TYPE[$index]"/>
    <xsl:value-of select="$dot/PRODUCT_LIST/PRODUCT_INFO[(PRODUCT_TYPE eq $product_name)]/UA"/>
</xsl:for-each>

尽管正如其他答案所指出的那样,从长远来看,重组代码以使用更标准的 XSLT 处理样式而不是简单地尝试移植您熟悉的 for(int i = 0; i < arr.length; i++) 结构会更好来自更多命令式编程语言。是的,习惯更函数式的思维方式需要一段时间,但在长期 运行.

中,它会导致更简单、更易于维护的代码

你为什么不简单地改变:

<xsl:for-each select="1 to count($PRODUCT_TYPE)">

<xsl:for-each select="$PRODUCT_TYPE">

那么你将处于<PRODUCT_TYPE>的上下文中,你只需要:

<xsl:value-of select="../UA"/>

直接获取同级 <UA> 值,无需像您那样进行复杂的扩展。


更简单的方法是将第一个变量定义为:

<xsl:variable name="PRODUCT_INFO" select="PRODUCT_LIST/PRODUCT_INFO[(PRODUCT_TYPE eq 'Chargeable Bonus Product') or (PRODUCT_TYPE eq 'Home Zone') or (PRODUCT_TYPE eq 'Usage Subscription- Traffic') or (PRODUCT_TYPE eq 'Telescopic Charging') or (PRODUCT_TYPE eq 'Usage Subscription- Recharge')]"/>

然后在:

<xsl:for-each select="$PRODUCT_INFO">

达到:

<xsl:value-of select="UA"/>

你真的不需要这里的任何变量

<xsl:template match="SUBSCRIBER">
    <!-- filter on PRODUCT_LIST/PRODUCT_INFO/PRODUCT_TYPE -->
    <xsl:apply-templates select="PRODUCT_LIST/PRODUCT_INFO[(PRODUCT_TYPE eq 'Chargeable Bonus Product') or (PRODUCT_TYPE eq 'Home Zone') or (PRODUCT_TYPE eq 'Usage Subscription- Traffic') or (PRODUCT_TYPE eq 'Telescopic Charging') or (PRODUCT_TYPE eq 'Usage Subscription- Recharge')]"/>
</xsl:template>

<xsl:template match="PRODUCT_INFO">
    <!-- Get relevant PRODUCT_INFO values -->
    <xsl:value-of select="UA"/>
</xsl:template>