首页 文章

在XSLT中匹配文本值

提问于
浏览
1

我遇到了一个奇怪的问题,让我撕裂了我的头发 . 我正在尝试在样式表中匹配XPath . 它在我对匹配值进行硬编码时起作用,但在我尝试从变量中获取时却不行 . 我在这做错了什么?

XML输入(显然非常简化):

<container>
      <items>
        <item>
          <LocationID>LOCATION_4</LocationID>
        </item>
        <item>
          <LocationID>LOCATION_4</LocationID>
        </item>
      </items>
    </container>

XSLT模板($ DistinctLocations和$ dataNode是以前声明的变量,我的前几个打印输出是验证它们都在范围内)

<xsl:template name="LocationTemplate">

      <xsl:for-each select="$DistinctLocations/Location">
        <MY-CURRITEM>
          <val>
            <xsl:copy-of select="." />
          </val>
          <distinct>
            <xsl:copy-of select="$DistinctLocations" />
          </distinct>
          <node>
            <xsl:copy-of select="$dataNode" />
          </node>
          <itemloc>
            <xsl:copy-of select="$dataNode//item[LocationID = 'LOCATION_4'][1]/LocationID" />
          </itemloc>
          <itemlocdot>
            <xsl:copy-of select="$dctNode//risk[LocationID = .][1]/LocationID" />
          </itemlocdot>
          <itemloctext>
            <xsl:copy-of select="$dctNode//risk[LocationID = text()][1]/LocationID" />
          </itemloctext>
          <itemloc2>
            <xsl:copy-of select="$dataNode//item[string(LocationID) = string(.) ][1]/LocationID" />
          </itemloc2>
          <itemloc3>
            <xsl:copy-of select="$dataNode//item[string(LocationID) = string(text()) ][1]/LocationID" />
          </itemloc3>
        </MY-CURRITEM>
      </xsl:for-each>
    </xsl:template>

输出:

<MY-CURRITEM>
  <val>
    <Location>LOCATION_4</Location>
  </val>
  <distinct>
    <DistinctLocations>
      <Location>LOCATION_4</Location>
    </DistinctLocations>
  </distinct>
  <node>
    <container>
      <items>
        <item>
          <LocationID>LOCATION_4</LocationID>
        </item>
        <item>
          <LocationID>LOCATION_4</LocationID>
        </item>
      </items>
    </container>
  </node>
  <itemloc>
    <LocationID>LOCATION_4</LocationID>
  </itemloc>
  <itemlocdot />
  <itemloctext />
  <itemloc2 />
  <itemloc3 />
</MY-CURRITEM>

如您所见,我对该值进行硬编码的节点返回匹配项 . 我尝试匹配变量值的所有其他函数都无法匹配 . 由于硬编码有效,我猜测它是类型之间的某种不匹配,但我已经尝试了所有我能想到的类型转换组合,但我没有得到任何结果 .

EDIT :人们正在请求整个样式表 . 它是's huge and will take some time to simplify. In the mean time, here' s变量来自哪里:

$ DistinctLocations是从C#传入的参数

args.AddParam("DistinctLocations", string.Empty, xDistinctLocs.CreateNavigator().Select("/"));

<xsl:param name="DistinctLocations" />

$ dataNode是正在转换的原始XML,存储在变量中:

<xsl:variable name="dataNode" select="." />

1 回答

  • 1

    请注意以下简化示例:

    XML

    <root>
        <locations>
            <location>LOCATION_2</location>
        </locations>
        <items>
            <item>
                <id>1</id>
                <location>LOCATION_1</location>
            </item>
            <item>
                <id>2</id>
                <location>LOCATION_2</location>
            </item>
        </items>
    </root>
    

    XSLT

    <xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
    <xsl:strip-space elements="*"/>
    
    <xsl:template match="/root">
        <xsl:copy>
            <xsl:for-each select="locations/location">
                <location>
                    <value>
                        <xsl:value-of select="." />
                    </value>
                    <hard-code>
                        <xsl:copy-of select="//item[location='LOCATION_2']" />
                    </hard-code>
                    <dot>
                        <xsl:copy-of select="//items/item[location=.]" />
                    </dot>
                    <current>
                        <xsl:copy-of select="//items/item[location=current()]" />
                    </current>
                </location>          
          </xsl:for-each>
        </xsl:copy>     
    </xsl:template>
    
    </xsl:stylesheet>
    

    Result

    <?xml version="1.0" encoding="utf-8"?>
    <root>
       <location>
          <value>LOCATION_2</value>
          <hard-code>
             <item>
                <id>2</id>
                <location>LOCATION_2</location>
             </item>
          </hard-code>
          <dot/>
          <current>
             <item>
                <id>2</id>
                <location>LOCATION_2</location>
             </item>
          </current>
       </location>
    </root>
    

    为什么结果的 <dot> 元素为空?因为在表达式中:

    "//items/item[location=.]"
    

    内部点表示外部 item 节点 - 而不是当前的 location 节点 . 表达式正在查找 item ,其值等于其 location 子元素的值 . 当然,不存在这样的项目 .

    这就是为什么XSLT添加了current() function,它在谓词中使用时不会改变上下文 .

相关问题