此处不能使用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>
在此先感谢您的支持。
我有以下 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>