【问题标题】:XSLT Filter not workingXSLT 过滤器不工作
【发布时间】:2017-12-20 22:37:24
【问题描述】:

我的计数正常,但是当我进一步过滤到 CODE='A' 或'B' 时,对于 NODE GUID=“2”,我也得到了“C”。

它看起来相当简单,但我不确定我做错了什么。

任何帮助将不胜感激。提前致谢。

有关 XPATH 表达式,请参阅 XSLT。

这是我的 XML:

<?xml version="1.0" encoding="UTF-8"?>
<NODEs>
    <NODE GUID="2">
        <Name>Michael</Name>
        <Activities/>
    <NODEs>
        <NODE GUID="1">
            <Name>Larry</Name>
            <ParentNODE>2</ParentNODE>
            <Activities>
                <Activity GUID="A1">
                    <ActivityCodes>
                        <ActivityCode>
                            <CodeTypeName>CODE</CodeTypeName>
                            <CodeValue>A</CodeValue>
                        </ActivityCode>
                   </ActivityCodes>
               </Activity>
           </Activities>
       </NODE>
       <NODE GUID="2">
           <Name>Joe</Name>
           <ParentNODE>2</ParentNODE>
           <Activities>
              <Activity GUID="A2">
              <NODECode>2</NODECode>
              <ActivityCodes>
                  <ActivityCode>
                      <CodeTypeName>CODE</CodeTypeName>
                      <CodeValue>A</CodeValue>
                  </ActivityCode>
              </ActivityCodes>
          </Activity>
          <Activity GUID="A3">
              <NODECode>2</NODECode>
              <ActivityCodes>
                  <ActivityCode>
                      <CodeTypeName>CODE</CodeTypeName>
                      <CodeValue>C</CodeValue>
                  </ActivityCode>
              </ActivityCodes>
          </Activity>
          <Activity GUID="A4">
             <NODECode>2</NODECode>
             <ActivityCodes>
                 <ActivityCode>
                     <CodeTypeName>CODE</CodeTypeName>
                     <CodeValue>B</CodeValue>
                 </ActivityCode>
             </ActivityCodes>
         </Activity>
      </Activities>
    </NODE>
   </NODEs>
  </NODE>
 </NODEs>

这是相关的 XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0"
    xmlns:saxon="http://saxon.sf.net/"
    xmlns:PS="http://localhost"
    exclude-result-prefixes="saxon PS">

  <xsl:apply-templates select=".//Activity" mode="I_NODE">                
  </xsl:apply-templates>

  <xsl:template match="Activity" mode="I_NODE">
    <xsl:variable name="Code" select="ActivityCodes/ActivityCode[CodeTypeName = 'CODE']/CodeValue"/>  <!-- 'A'/'B' -->

    <xsl:if test="$Code = 'A' or $Code = 'B'">
      <NODE>
        <xsl:variable name="Count" select="count(preceding-sibling::*[$Code = 'A' or $Code = 'B'] ) +1"/>
        <xsl:value-of select="$Count"/>    
      </NODE>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

当前输出:

<NODE>1</NODE>
<NODE>1</NODE>
<NODE>3</NODE>

预期输出:

<NODE>1</NODE>
<NODE>1</NODE>
<NODE>2</NODE>

【问题讨论】:

  • 您使用的 XPath 来自什么上下文?仅使用 XPath 进行调试有点困难。此外,该 XPath 无效。 stackoverflow.com/help/mcve
  • 它来自 xslt:
  • 所讨论的 XPath 表达式在您编辑的 XSLT 中的形式与您最初询问的独立 XPath 表达式的形式有些不同。新表达式还使用了一个变量$SAPInternalCode,它没有在任何地方定义。也许你的意思是$Code 那里,但如果是这样,那么我不认为这个表达意味着你认为它的意思。特别是,它与您最初发布的表达方式不同。
  • 是的,我的意思是 $Code。我尝试了谓词的许多变体并发布了不正确的谓词。然而,应该有一个有效的谓词。 If 语句仅处理输出中可以证明的 A 和 B 代码。 1 个输出给拉里,2 个输出给乔。问题在于计数谓词,Larry 的计数应该是 2,但无论我尝试什么,它都会出现 3。必须有一个合乎逻辑的解释。

标签: xml xslt xpath xslt-1.0


【解决方案1】:

您的 XPath 似乎有问题:

count(preceding-sibling::*[ActivityCodes/ActivityCode[CodeTypeName = 'CODE']/CodeValue = 'A'] or [ActivityCodes/ActivityCode[CodeTypeName = 'CODE']/CodeValue = 'B'] ) +1

看起来您的意思是or 条件位于谓词内部而不是两个谓词之间:

count(preceding-sibling::*[ActivityCodes/ActivityCode[CodeTypeName = 'CODE']/CodeValue = 'A' or ActivityCodes/ActivityCode[CodeTypeName = 'CODE']/CodeValue = 'B'] ) +1

这将计算上下文节点的所有前面的兄弟节点,其中 ActivityCode 有一个 CodeTypeName 子节点,其值为 'CODE'CodeValue 的值为 'B'。不过,您应该能够更紧凑地表达同一件事:

count(preceding-sibling::*[ActivityCodes/ActivityCode[CodeTypeName = 'CODE'][CodeValue = 'A' or CodeValue = 'B'] ) +1

就个人而言,我发现更紧凑的版本也更清晰。

【讨论】:

  • 这很奇怪。我尝试了这两个版本,在这两种情况下,节点 2 的计数均为 3,因此仍在计算“C”。我想对于紧凑的版本应该在 ')' 之前有一个 ']'。
  • 我也尝试将路径放入变量中,但名称为“Joe”的节点仍然计数为 3:
  • @jkoul,请注意,您的表达式末尾有一个 +1,这是我的。
  • 注明。我已经编辑了我的帖子以包含上面的相关 XSLT。我仍然不知道为什么@John Bollinger 的两个答案和上面 XSLT 中的一个没有产生正确的输出。有人有想法吗?
  • @Jkoul,如果我将此答案中已经建议的确切 XPath 表达式替换为您的 XSLT,作为 $Count 变量值的表达式,(并修复一两个次要但看似无关的其中的问题)然后生成的转换会产生您想要的输出,而不是您声称获得的输出。
【解决方案2】:

如果您只是想计算所有ActivityCode 块的数量,其中CodeTypeName = 'CODE'CodeValue = 'A'+1 然后使用计数如下:

count(//ActivityCode[CodeTypeName = 'CODE' and CodeValue = 'A']) + 1

结果:

3

但是,如果您想计算所有 CodeTypeName = 'CODE'NODE 中的 NODEGUID = '2'+1 (如上)块中的块的数量,如下所示:

count(/NODEs/NODE[@GUID = '2']/NODEs/NODE[@GUID = '2']//ActivityCode[CodeTypeName = 'CODE' and CodeValue = 'A']) + 1

结果:

2

【讨论】:

  • 谢谢@O.F.但是可以有几个嵌套级别的节点/节点。我的示例 XML 是一个非常小的 sn-p 数据。
猜你喜欢
  • 2012-08-01
  • 2023-03-21
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多