2

グローバル変数は、さまざまな種類の要素ごとに、処理する必要のある属性を示します。

<xsl:variable name="attributes.rtf">
  <element name="measure">
    <att>type</att>
    <att>quantity</att>
    <att>unit</att>
  </element>
  <element name="milestone">
    <att>n</att>
  </element>
  <element name="lb">
    <att>ed</att>
    <att>type</att>
    <att>subtype</att>
    <att>n</att>
  </element>
</xsl:variable>
<xsl:variable name="attributes" select="exslt:node-set($attributes.rtf)" /> <!-- This is XSLT 1.0 -->

コンテキストが要素である場合、その種類の要素の属性をループするfor-eachが必要です。1つのXPath式でこれを行う方法がわかりません。今私はこれらの2つを持っています:

 <xsl:variable name="temp" select="." />                            <!-- For, say, a <measure> element, -->
 <xsl:for-each select="$attributes/element[@name=name($temp)]/att"> <!-- loop through the names "type", "quantity", and "unit" -->
      <xsl:for-each select="$temp/@*[name()=current()]">            <!-- If an attribute of that name exists in the current <measure> element  -->
                                                                    <!-- (now stored as $temp), then process that attribute. --> 
      </xsl:for-each>
 </xsl:for-each>

$ tempを作成せずに、1つの式でこれを行う方法はありますか?

ただし、コンテキスト要素にリストされている属性のいずれかが含まれているかどうかを示す外部テスト条件も必要です。そのテストのために、私は一つの表現が欲しいです。

(属性の処理は順序付けする必要があるため、2つのループが必要になる場合があります。ただし、順序はテスト条件には関係ありません。したがって、1つの式でそれを実行できる可能性があります。)

4

1 に答える 1

2

I.「単純な」問題

When the context is an element, I need a for-each that will loop through attributes for that kind of element.

いいえxsl-for-each、必要ありません。

I don't see how to do this in one XPath expression.

使用するだけです:

<xsl:apply-templates select=
  "@*[name()=$attributes/element[@name=name(current())]/att]"/>

説明

機能の適切な使用current()


II。「複雑な」問題

Processing of the attributes does need to be ordered, so maybe that requires the two loops

これは、 :で指定された順序で属性を生成するために他のネスト <xsl:apply-templates> が必要ないことを示す完全な例です。$attributes

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:exslt="http://exslt.org/common">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

    <xsl:variable name="attributes.rtf">
        <element name="measure">
            <att>type</att>
            <att>quantity</att>
            <att>unit</att>
        </element>
        <element name="milestone">
            <att>n</att>
        </element>
        <element name="lb">
            <att>ed</att>
            <att>type</att>
            <att>subtype</att>
            <att>n</att>
        </element>
    </xsl:variable>

    <xsl:variable name="attributes" select="exslt:node-set($attributes.rtf)" />

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

 <xsl:template match="t/*">
  <xsl:copy>
      <xsl:apply-templates select="$attributes/element[@name=name(current())]/att">
        <xsl:with-param name="pCurrent" select="current()"/>
      </xsl:apply-templates>
      <xsl:apply-templates select=
       "@*[not(name() = $attributes/element[@name=name(current())]/att)]"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="att">
   <xsl:param name="pCurrent" select="/.."/>

  <xsl:if test="$pCurrent[@*[name()=current()]]">
      <xsl:attribute name="{.}">
       <xsl:value-of select="concat(.,'-',.)"/>
      </xsl:attribute>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

この変換が次のXMLドキュメントに適用される場合(何も提供されませんでした!!!):

<t>
  <lb type="normal" ed="uni" n="3"
      subtype="initial" other="yes"/>
  <milestone n="2" other="yes"/>
  <measure quantity="3" unit="cm"
           type="length" other="yes"/>
</t>

必要な正しい結果が生成されます:

<t>
   <lb ed="ed-ed" type="type-type" subtype="subtype-subtype" n="n-n" other="yes"/>
   <milestone n="n-n" other="yes"/>
   <measure type="type-type" quantity="quantity-quantity" unit="unit-unit" other="yes"/>
</t>
于 2012-08-04T23:30:52.337 に答える