String XSLT通过比较元素文本和子字符串结果来查找匹配节点

String XSLT通过比较元素文本和子字符串结果来查找匹配节点,string,xslt,comparison,String,Xslt,Comparison,我正在处理此XML: <Brand> <Brand_Name>BLENDERM</Brand_Name> <Brand_Code>1103</Brand_Code> <Groups> <Group> <Group_Code>657</Group_Code> <Parent_Code>0</Parent_Code> <Group_Level>1</G

我正在处理此XML:

<Brand>
<Brand_Name>BLENDERM</Brand_Name>
<Brand_Code>1103</Brand_Code>
<Groups>
<Group>
<Group_Code>657</Group_Code>
<Parent_Code>0</Parent_Code>
<Group_Level>1</Group_Level>
<Group_Name>Brand Default</Group_Name>
<Product>
<Pip_code>0032359</Pip_code>
<Status>In Use</Status>

布伦德
1103
657
0
1.
品牌违约
0032359
使用中
使用此XSLT:

<xsl:template match="Product" mode="phase-3">
<xsl:value-of select="document('rx_catmapping.xml')/descendant::mapping[source=substring(ancestor::Brand/Brand_Name,1,1)]/target"/>
</xsl:template>

以下是rx_catmapping.xml的示例:

<Lookup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <mapping>
        <source>a</source>
        <target>788</target>
    </mapping>
    <mapping>
        <source>B</source>
        <target>789</target>
    </mapping>
</Lookup>

A.
788
B
789
所以,我在处理产品元素,它是品牌的后代。在本例中,
Brand/Brand\u Name
的第一个字母是B,我试图通过在rx\u catmapping.xml中查找来输出值789。这应该很简单,但我完全被难倒了!我尝试将XPath的第一部分更改为引用
文档('rx_catmapping.xml')/Lookup/mapping
,或
文档('rx_catmapping.xml')//mapping
。我还尝试将比较的前半部分更改为
string(source)
,或
source/text()
,但这两种方法都不起作用。(尝试这样做的原因是,例如,使用
source='B'
似乎确实有效,所以我想知道我是否在尝试比较两种不兼容的数据类型。)

提前感谢您的帮助。

定义密钥

<xsl:key name="k1" match="mapping" use="source"/>

然后使用

<xsl:variable name="map-doc" select="document('rx_catmapping.xml')"/>


使用XSLT2.0,您可以将其简化为

<xsl:value-of select="key('k1', substring(ancestor::Brand/Brand_Name,1,1), $map-doc)"/>

我认为,问题在于,在您执行
祖先::品牌/品牌名称
时,上下文是外部文件中的
映射
元素。这对我有用

  <xsl:template match="/">
    <xsl:apply-templates select=".//Product"/>
  </xsl:template>
  <xsl:template match="Product">
    <xsl:variable name="x" select="substring(ancestor::Brand/Brand_Name,1,1)"/>
      <xsl:value-of select="document('file:///c:/temp/rx_catmapping.xml')//mapping[source=$x]/target"/>
  </xsl:template>


此后,我找到了另一种可行的方法,使用
xsl:key
。但如果有人能解释为什么我以前的方法不起作用,我还是会非常感激的——我肯定为此花了好几个小时的时间上下文对于XPath和XSLT很重要,您希望
在谓词中比较
映射
子元素与当前
产品
祖先::品牌/品牌名称
(而不是代码示例尝试的
映射
)`
  <xsl:template match="/">
    <xsl:apply-templates select=".//Product"/>
  </xsl:template>
  <xsl:template match="Product">
    <xsl:variable name="x" select="substring(ancestor::Brand/Brand_Name,1,1)"/>
      <xsl:value-of select="document('file:///c:/temp/rx_catmapping.xml')//mapping[source=$x]/target"/>
  </xsl:template>