0

私は xslt に比較的慣れていませんが、巨大な xml ファイルのスタイルを整えることができました。今、私はある場所で立ち往生しており、先に進むことができません。xmlファイルの構造が次のようになっているとしましょう

<xxx>
.......
.......
.......
 <Field id="123" type="fld" elem="3">
   <td:value passed="true"> 25 </td:value>
 </Field>
.......
.......
.......

</xxx>

現在、フィールド ノードにいます。実行する<xsl:value of select="name()" />と「Field」が表示され、実行すると<xsl:value of select="@type" />「fld」が表示されます。しかし、私がやると、<xsl:value of select="." />その中の値<td:value>は25になります。

私の懸念は、td:value 内の「渡された」属性の値を取得する必要があることです。現在の場所から次のテンプレートを使用すると、属性にアクセスできます。

<xsl:apply-templates select="*[@passed]" />

  <xsl:template match="*[@passed]" >
       <xsl:value-of select="@passed" />
     </xsl:template>

<td:value>しかし、問題は、「渡された」属性が常に存在するとは限らないため、ノード名だけでノードに到達する必要があることです。

私は試した

<xsl:apply-templates select=".//td" />
<xsl:apply-templates select=".//td:value" />
<xsl:apply-templates select=".//*" />
<xsl:apply-templates select=".*" />
<xsl:apply-templates select="td" />

何も機能していないようです。Field ノードからその td:value ノードにアクセスするにはどうすればよいですか?

4

2 に答える 2

2

入力 XMLのtdプレフィックスに割り当てられているのと同じ名前空間を宣言する必要があります。td:value例えば:

<foo xmlns:td="urn:td">
  <Fieldid="123" type="fld" elem="3">
    <td:value passed="true"> 25 </td:value>
  </Field>
</foo>

XSLT は次のようになります。

<xsl:template match="Field">
  <xsl:if test="td:value@passed" xmlns:td="urn:td">
    <xsl:value-of select="td:value"/>
  </xsl:if>
</xsl:template>

重要な部分は、名前空間が入力ドキュメントと同じであることです。XSLT ドキュメントのプレフィックスの名前が異なっていても問題ありません。可能であれば、すべての XML が管理下にある場合は、わかりやすくするために管理する必要があります。

于 2012-11-01T17:04:22.870 に答える
1

明確にするために、現在フィールド要素に配置されており、子td:valueを選択してその@passed属性を取得しようとしていますが、この属性が存在しない場合は、要素の値を取得する必要があります代わりは。

さて、あなたが最初にできることは、これを置き換えることです

<xsl:apply-templates select="*[@passed]" />

これだけで

<xsl:apply-templates select="*" />

次に、一致する 2 つのテンプレートが必要です。1 つは属性が存在する場合、もう 1 つはその他のケースをキャプチャするためのものです。

<xsl:template match="Field/*[@passed]" >
   <xsl:value-of select="@passed" />
</xsl:template>

<xsl:template match="Field/*" >
   <xsl:value-of select="." />
</xsl:template>

このような 2 つのテンプレートがある場合、XSLT はより具体的なテンプレートを最初に照合します。したがって、@passed属性が存在する場合、最初のテンプレートは常に一致します (2 番目のテンプレートも一致しますが)。プレゼントが1つもない場合は、2つ目を使用します。

編集:要素名を指定したくない場合は、テンプレートをこれだけに置き換えることができます...

<xsl:template match="*[@passed]" >
   <xsl:value-of select="@passed" />
</xsl:template>

<xsl:template match="*" >
   <xsl:value-of select="." />
</xsl:template>

ただし、これらは、XSLT の他の部分に影響を与える可能性のあるすべての要素に一致し始めます。したがって、ここでモードパラメータを使用する必要があるかもしれません

<xsl:apply-templates select="*" mode="Field" />

<xsl:template match="*[@passed]" mode="Field" >
   <xsl:value-of select="@passed" />
</xsl:template>

<xsl:template match="*" mode="Field" >
   <xsl:value-of select="." />
</xsl:template>
于 2012-11-01T17:00:08.610 に答える