0

複数のソースによって生成された XML の一部を変換しようとしています。テキストを value-of select ステートメントに直接入力すると、意図したとおりに機能します。しかし、変数を使用しようとするとすぐに機能しなくなります。

xsl:for-each ステートメントで変数を使用すると、それも正常に機能します。これは正常に動作する 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:value-of select 内で変数を使用すると、次のコード ブロックで指定されているように機能しません。「firstname」、「firstname | fname」で1つの変数のみを使用したり、テキストを連結(...)しようとしたりするなど、多くの組み合わせを試しました...

<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>

変数に「account/firstname」を指定したため、結果が得られたのは1回だけです。しかし、この方法では、すべての for-each 反復でのみ最初の要素の値を常に取得しました。変数を指定するときにコンテキストが失われるようです (プロセッサは現在「アカウント」エンティティ内にあり、「ファーストネーム」をサブノードとして選択する必要があります)。

XSLT 1.0 から 2.0 への select ステートメントの値で何かが変更されたことを読みましたが、違いが何であるかを完全には理解していません (私は XSLT にかなり慣れていません)。

XSL を機能させるには、どのように 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>

編集:私が言及すべきだったのは、これらのテンプレートは変更される/変更される可能性があるため、すべての「変数」が1か所にあると簡単になるということです。ターゲットの名前が「連絡先」ではなく、別のものである可能性があり、ドキュメント全体でそれを変更すると、エラーが発生しやすく冗長になります。また、これらの変数は、XmlReader によって読み取られる別のプロセスで使用されます。構成の煩わしさと冗長性をできるだけ低く保つようにしています。

4

3 に答える 3

1

検討したい可能性のある 2 つのアプローチを次に示します。1 つは変数を使用して、呼び出したい要素の可能なすべての名前を格納します。もう 1 つは、親内の要素の位置がわかっていると想定しているため、名前は重要ではありません。

次のスタイルシートは両方のメソッドを示しています。前者は親要素用、後者はfirstname子要素用です。

<?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>
于 2014-02-06T10:20:03.677 に答える
0

問題は、XSLT の変数が不変であることです。それらを定数として扱います。あなたがしたとき

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

現在のコンテキストで「firstname」を選択しました。コンテキスト内のコードだと思う<xsl:template match='root'>ので、「root/firstname」を選択しました。そのようなノードはないため、結果は予想どおり空です。

for-each で変数を呼び出すと、単に変数の内容が出力されますが、これは何もありません。

変数はそのノードが存在するためだと言ったときに機能しましたaccount/firstnameが、変数は実際には定数であるため、最初の一致の内容が含まれており、その値を変更しようとする他の試みは無視されました。

于 2014-02-05T14:43:38.657 に答える
0

XSLT では、知っている手続きパラダイムを忘れる必要があります。xsl:for-each不適切な場合は避けて、代わりに別のテンプレートを作成する必要があります。

同様に、あなたのケースでは変数を使用する必要はありません。つまり、それらを使用することは不可能ではありませんが、@helderdarocha が指摘したように、それらの不変性とコンテキストに注意する必要があります。

表示するスタイルシートでは、選択した要素がそのコンテキストに存在しないため、ほとんどの変数が空である可能性があります。要素が階層内のどこにあるかに関係なく要素を選択するには、式を で始めます//

スタイルシート

<?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>
于 2014-02-05T15:01:14.937 に答える