XSLT 1.0无法在XSL中选择变量:选择值



我尝试转换由多个来源生成的XML。如果我将文本直接输入到"选择值"语句中,则它会按预期工作。但是,一旦我尝试使用变量,它就不会再起作用了。

如果我在XSL中使用变量:for-east语句,它也可以正常工作。这是正常工作的XSL

<xsl:variable name="crm_acc" select="account" />
<xsl:variable name="nav_acc" select="kontakt" />
<xsl:variable name="crm_fname" select="firstname" />
<xsl:variable name="nav_fname" select="fname" />
<TreeView>
  <xsl:for-each select="$crm_acc | $nav_acc">
    <TreeViewItem Header="Item">
      <TreeViewItem Header="Firstname:" >
        <xsl:value-of select="firstname | fname" />
      </TreeViewItem>
    </TreeViewItem>
  </xsl:for-each>
</TreeView>

但是,如果我使用xsl:选择值之内的变量,那只是在下一个代码块中指定的不起作用。我尝试了很多组合,例如仅将一个变量与" firstName"," firstName | fname"一起使用,试图concat(...)文本等...

<TreeView>
  <xsl:for-each select="$crm_acc | $nav_acc">
    <TreeViewItem Header="Item">
      <TreeViewItem Header="Firstname:" >
        <xsl:value-of select="$crm_fname | $nav_fname" />
      </TreeViewItem>
    </TreeViewItem>
  </xsl:for-each>
</TreeView>

输入XML:

<?xml version='1.0'?>
<root>
  <account system="CRM">
    <firstname>test1</firstname>
  </account>
  <account system="CRM">
    <firstname>test2</firstname>
  </account>
  <kontakt system="NAV">
    <erstername>nav1</erstername>
  </kontakt>
</root>

只有在变量中指定的"帐户/firstName"时才能获得结果。但是,这样,我总是只有在每个详细的迭代中才能获得第一个元素的价值。似乎它在指定变量时会丢失上下文(处理器当前位于"帐户"实体中,应该选择" firstName作为子节点)。

我读到,在XSLT 1.0到2.0的选择值语句中发生了一些变化,但我不完全理解区别是什么(我是XSLT的新手)。

我必须如何指定XSL才能工作?

更新:预期输出与代码块1

<?xml version="1.0" encoding="UTF-8"?>
<TabItem xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Header="Xaml Accounts Tab">
  <TreeView>
    <TreeViewItem Header="CRM">
       <TreeViewItem Header="Firstname:">test1</TreeViewItem>
    </TreeViewItem>
    <TreeViewItem Header="CRM">
       <TreeViewItem Header="Firstname:">test2</TreeViewItem>
    </TreeViewItem>
    <TreeViewItem Header="NAV">
       <TreeViewItem Header="Firstname:">nav1</TreeViewItem>
    </TreeViewItem>
  </TreeView>
</TabItem>

编辑:我应该提到的是这些模板将/可以修改,因此如果所有"变量"都在一个地方,则会更容易。可能是目标不是"联系",而是其他内容,并且在整个文档中更改它是错误的和多余的。另外,这些变量在XMLReader读取的另一个过程中使用。我尝试使配置和冗余的麻烦尽可能低。

这是您可能想要探索的两种可能的方法:一个使用变量存储您可能希望调用的元素的所有可能的 name ;另一个假定其父元素的位置是已知的,因此名称并不重要。

以下样式显示了这两种方法,前者是父元素,后者的 firstName child。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:variable name="CRM">
    <name>account</name>
    <name>kontakt</name>
</xsl:variable>
<xsl:template match="/">
<TreeView>
    <xsl:for-each select="root/*[local-name()=exsl:node-set($CRM)/name]">
        <TreeViewItem Header="{@system}">      
            <TreeViewItem Header="Firstname:" >
                <xsl:value-of select="*[1]" />
            </TreeViewItem>
        </TreeViewItem>
  </xsl:for-each>
</TreeView>
</xsl:template>
</xsl:stylesheet>

问题是XSLT中的变量是不变的。将它们视为常数。当你做

<xsl:variable name="crm_fname" select="firstname" />

您在当前上下文中选择了" firstName"。我想该代码在<xsl:template match='root'>上下文中,因此您选择了" root/firstName"。没有这样的节点,因此结果如预期为空。

当您调用for-east中的变量时,您只是在打印变量的内容,这是什么。

当您说变量为 account/firstname时,它起作用,因为该节点存在,但是由于变量实际上是常数,因此它包含了第一个匹配的内容,并且任何其他更改该值的尝试都被忽略了。

<。

在XSLT中,您必须忘记您知道的任何程序范例。您应该在不适当的情况下避免使用xsl:for-each,然后编写单独的模板。

同样,在您的情况下也无需使用变量。也就是说,使用它们并非不可能,但是,正如@helderdarocha所指出的那样,您必须意识到它们的不变性和 context

在您显示的样式表中,大多数变量很可能是空的,因为您选择的元素在该上下文中不存在。要选择元素,无论它们在层次结构中的位置如何,请用//开始表达式。

样式表

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>
   <xsl:template match="/root">
      <TabItem xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Header="Xaml Accounts Tab">
         <TreeView>
            <xsl:apply-templates/>
         </TreeView>
      </TabItem>
   </xsl:template>
   <xsl:template match="account|kontakt">
      <TreeViewItem  Header="{@system}">
         <xsl:apply-templates/>
      </TreeViewItem>
   </xsl:template>
   <xsl:template match="firstname|erstername">
      <TreeViewItem  Header="Firstname:">
         <xsl:value-of select="."/>
      </TreeViewItem>
   </xsl:template>
</xsl:stylesheet>

输出

<?xml version="1.0" encoding="UTF-8"?>
<TabItem xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         Header="Xaml Accounts Tab">
   <TreeView>
      <TreeViewItem xmlns="" Header="CRM">
         <TreeViewItem Header="Firstname:">test1</TreeViewItem>
      </TreeViewItem>
      <TreeViewItem xmlns="" Header="CRM">
         <TreeViewItem Header="Firstname:">test2</TreeViewItem>
      </TreeViewItem>
      <TreeViewItem xmlns="" Header="NAV">
         <TreeViewItem Header="Firstname:">nav1</TreeViewItem>
      </TreeViewItem>
   </TreeView>
</TabItem>

相关内容

  • 没有找到相关文章

最新更新