2011-10-04 2 views
2

私は、固有のIDを生成するXML文書を持っています。いくつかのノードは既に属性を持っているかもしれません。その場合、これは置き換えられます。ドキュメント内のすべてのノードに属性が必要です。XSL - コピー時の属性の更新または作成

文書例は、私は、次のスタイルシート

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" omit-xml-declaration="yes"/> 

    <xsl:template match="*"> 
     <xsl:copy> 
      <xsl:attribute name="uid"> 
       <xsl:value-of select="generate-id(.)"/> 
      </xsl:attribute> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

を使用していますが、次の出力を取得しています

<root> 
<anode uid='123'/> 
<anode/> 
</root> 

だろう。これは私が望むものに近いですが、既存のIDがテキストノードとして作成されないようにするにはどうすればよいですか?

<root uid="id515559"> 
<anode uid="id515560">123</anode> 
<anode uid="id515562"/> 
</root> 

私はXSLT: How to change an attribute value during <xsl:copy>?を見てきましたが、私は、これは新しい属性を作成するために得ることができませんでした。

違いがある場合は、lxmlを使用してスタイルシートを処理しています。 Built-in template rule

答えて

0

はラインで入力@uidに適用されている:

<xsl:apply-templates select="@*|node()"/> 

属性コピーのデフォルトのテンプレートテキスト、テンプレートこのように定義されたかのように振舞う:

<xsl:template match="text()|@*"> 
    <xsl:value-of select="."/> 
</xsl:template> 

これが適用されないようにするには、属性に適用されないようにapply-templatesの選択属性を変更するか、任意の属性に対して新しい空白のテンプレートを定義するかのいずれかを選択します。

<xsl:template match="@*" /> 
あなたも、このように、唯一の uid属性を無視するように類似したテンプレートを使用して、より具体的な可能性があり

<xsl:template match="@uid" /> 
1

あなたがする必要があるのは、既存ののuid属性に一致するようにテンプレートを追加することです、そして...このスタイルシートで、だから... ...

<xsl:template match="@uid" /> 

をそれを無視

あなたのサンプルXMLに適用すると、以下のように
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" omit-xml-declaration="yes"/> 

    <xsl:template match="*"> 
     <xsl:copy> 
     <xsl:attribute name="uid"> 
      <xsl:value-of select="generate-id(.)"/> 
     </xsl:attribute> 
     <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="@uid" /> 
</xsl:stylesheet> 

、出力は次のようになります。

<root uid="IDAEQLT"> 
    <anode uid="IDA3XLT"></anode> 
    <anode uid="IDA0XLT"></anode> 
</root> 
0

答えは本当に@uidをオーバーライドする新しい一致を追加するほど極端ではありません。 xsl:apply-templatesからselectを削除するだけです。削除select

あなたのスタイルシート:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" omit-xml-declaration="yes"/> 

    <xsl:template match="*"> 
     <xsl:copy> 
      <xsl:attribute name="uid"> 
       <xsl:value-of select="generate-id(.)"/> 
      </xsl:attribute> 
      <xsl:apply-templates/> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

は、次の出力が生成され(@uidは異なります):

<root uid="d0e1"> 
    <anode uid="d0e3"/> 
    <anode uid="d0e5"/> 
</root> 
関連する問題