XSLT 2.0 Xpath错误“;“不是节点项”;

XSLT 2.0 Xpath错误“;“不是节点项”;,xslt,key,xslt-2.0,Xslt,Key,Xslt 2.0,我的第一篇文章在这里-当然希望有人会知道答案! 我已经能够为我遇到的许多问题找到解决方案,但这次没有。 这个网站上关于同一主题的问题和答案并没有解决我的问题 我有一个包含如下格式规范的xml <Format> <TagNr>92</TagNr> <Option>A</Option> <Format>//[N]15d</Format> </Format> <Format&g

我的第一篇文章在这里-当然希望有人会知道答案! 我已经能够为我遇到的许多问题找到解决方案,但这次没有。 这个网站上关于同一主题的问题和答案并没有解决我的问题

我有一个包含如下格式规范的xml

<Format>
    <TagNr>92</TagNr>
    <Option>A</Option>
    <Format>//[N]15d</Format>
</Format>
<Format>
    <TagNr>92</TagNr>
    <Option>B</Option>
    <Format>//3!a/3!a/15d</Format>
</Format>

92
A.
//[N] 15天
92
B
//3!a/3!a/15d
TagNr+选项是此节点集中的唯一组合

我定义了一个键,以便更轻松地使用这组格式:

<xsl:key name="xx" match="//Format/Format" use="concat(../TagNr, ../Option)"/>

我确实可以使用此键并获得正确的值,但只能在非特殊元素中使用;当在中为每个或其他结构(如下面的结构)使用此键时,我会遇到一个错误“XPath 2.0表达式中的错误不是节点项”

我试图实现以下目标:在处理的其他节点中,有一个选项字符串,我希望检索每个字符的格式。 例如:

<Tag>
    <TagNr>92</TagNr>
    <Options>AB</Options>
</Tag>

92
AB
我一直在尝试下面的许多变体,但运气不佳:

<xsl:variable name="TN"><xsl:value-of select="TagNr"/></xsl:variable>
<xsl:variable name="optList">
    <xsl:analyze-string select="./Options" regex="[A-Z]">
        <xsl:matching-substring>
            <xsl:variable name="TNO" select="concat($TN, .)"/>
            <opt>
                <tag><xsl:value-of select="$TNO"/></tag>
                <fmt><xsl:value-of select="key('xx', $TNO)"/></fmt>
            </opt>
        </xsl:matching-substring>
    </xsl:analyze-string>
</xsl:variable>

使用正则表达式拆分为单个字符会很好,当检索(仅)opt/tag的值时也会很好。 但是当我添加opt/fmt时,我遇到了Xpath表达式select=“key('xx',$TNO)”的错误消息

我尝试根据这个站点的另一个线程中建议的键函数定义一个变量,但没有成功


有人能帮我吗?

问题是,上下文在您的
analysis string
元素中发生了变化。也许下面的解决方案会对你有所帮助

对于这样的XML文件:

<a>
    <Format>
        <TagNr>92</TagNr>
        <Option>A</Option>
        <Format>//[N]15d</Format>
    </Format>
    <Format>
        <TagNr>92</TagNr>
        <Option>B</Option>
        <Format>//3!a/3!a/15d</Format>
    </Format>
    <Tag>
        <TagNr>92</TagNr>
        <Options>AB</Options>
    </Tag>
</a>

92
A.
//[N] 15天
92
B
//3!a/3!a/15d
92
AB
考虑以下XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
    <xsl:output indent="yes"/>
    <xsl:key name="xx" match="//Format/Format" use="concat(../TagNr, ../Option)"/>
    <xsl:template match="/">
        <result>
            <xsl:apply-templates select="//Tag"/>            
        </result>
    </xsl:template>
    <xsl:template match="Tag">
        <xsl:call-template name="createOPT">
            <xsl:with-param name="str" as="xs:string" select="Options"/>
        </xsl:call-template>                
    </xsl:template>
    <xsl:template name="createOPT">
        <xsl:param name="str"/>
        <xsl:if test="string-length($str) > 0">
            <xsl:variable name="firstChar" select="substring($str,1,1)"/>
            <xsl:variable name="TNO" select="concat(TagNr,$firstChar)"/>
            <opt>
                <tag><xsl:value-of select="$TNO"/></tag>
                <fmt><xsl:value-of select="key('xx', $TNO)"/></fmt>
            </opt>
            <xsl:call-template name="createOPT">
                <xsl:with-param name="str" select="substring($str,2)"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

结果是:

<?xml version="1.0" encoding="UTF-8"?>
<result>
   <opt>
      <tag>92A</tag>
      <fmt>//[N]15d</fmt>
   </opt>
   <opt>
      <tag>92B</tag>
      <fmt>//3!a/3!a/15d</fmt>
   </opt>
</result>

92A
//[N] 15天
92B
//3!a/3!a/15d

逐字符处理字符串的最简单XSLT 2.0方法如下所示:

<xsl:for-each select="string-to-codepoints($vStr)">
 <xsl:variable name="$vChar" select=
     "codepoints-to-string(.)"/>

 <!-- Process $vChar here: -->
</xsl:for-each/>
摘要

<xsl:for-each select="string-to-codepoints($vStr)">
 <xsl:variable name="$vChar" select=
     "codepoints-to-string(.)"/>

 <!-- Process $vChar here: -->
</xsl:for-each/>
  • 使用函数进行逐字符处理

  • 使用函数的第三个参数指定与当前上下文不同的上下文


  • key()函数(带两个参数)搜索包含上下文节点的文档。如果上下文项不是节点(例如,在analyze string中),则会出现此错误,因为它不知道要搜索哪个文档。答案是使用key()的第三个参数来提供此信息。

    谢谢-这肯定会让我重新开始!而且还提供了一种我原本想做的逐字符替换的方法。但有一个问题:失去了背景,但为什么?为什么在这个站点的另一个线程中没有更优雅的解决方案:定义变量以恢复上下文?您也可以使用变量来恢复上下文。也许它更优雅。我个人的看法是,
    analyze string
    的使用和维护有点困难,我更愿意在可能的情况下避免它。上下文没有丢失,但是在analyze string中,它不是一个节点,而是一个原子项,即当前正在处理的(子)字符串。感谢Martin指出这一点。我指的是前一种情况。我会更新的。超级家伙们-非常感谢你们的帮助。我想知道如何精确地指定键函数的第三个参数——是否会像“/”一样表示文档根?我在XSLT2.0指南中找不到这方面的信息。那么,“将原始文档上下文保存到变量中”是如何做到的呢?@Maestro13:像这样:
    ,并且这个变量定义可以是全局的(xsl:stylesheet)@Maestro13:我的答案(包括你的评论)有用吗?您仍然有问题吗?我为我的问题设计了另一个解决方案(使用analyze string将选项值列表保存到一个变量中,然后将列表与另一个包含格式的变量一起传递给命名模板)。但是,每当我觉得需要一个三参数的键函数调用时,我肯定会尝试你的建议。作为测试,我使用了建议的键函数的第三个参数,这非常有效。只保留分析字符串部分,而不是用建议的代码点来回替换,因为在我看来,使用分析字符串更清晰。