2

私はfile.xmlを持っています

<?xml version="1.0"?>
<Report>
      <row>
            <field1>test1</field1>
            <field2>test2</field2>
            <field3>test3</field3>
      </row>
      <row>
            <field1>test4</field1>
            <field2>test5</field2>
            <field3>test6</field3>
      </row>
</Report>

そしてlookup.xml

<?xml version="1.0"?>
<lookup>
      <field1>fieldA</field1>
      <field2>fieldB</field2>
      <field3>fieldC</field3>
</lookup>

次の出力を取得しようとしています

<?xml version="1.0"?>
<Report>
      <row>
            <fieldA>test1</fieldA>
            <fieldB>test2</fieldB>
            <fieldC>test3</fieldC>
      </row>
      <row>
            <fieldA>test4</fieldA>
            <fieldB>test5</fieldB>
            <fieldC>test6</fieldC>
      </row>
</Report>

これまでのところ、次の transform.xsl を思いつきました

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes"/>



  <xsl:variable name="lookupDoc" select="document('lookup.xml')"/>

  <xsl:template match="Report">
    <Items>
      <xsl:apply-templates/>
    </Items>
  </xsl:template>

  <xsl:template match="row">
    <Item>
      <xsl:apply-templates/>
    </Item>
  </xsl:template>

  <xsl:template match="row/*">
    <xsl:variable name="this" select="."/>
    <xsl:variable name="lookup">
      <xsl:for-each select="$lookupDoc">
        <xsl:key name="k1" match="local-name()" use="text()"/>
        <xsl:value-of select="key('k1', local-name($this))"/>
      </xsl:for-each>
    </xsl:variable>
    <fieldName name="{$lookup}">
      <xsl:value-of select="."/>
    </fieldName>
  </xsl:template>

</xsl:stylesheet>

Xsl が初めてなので、コンパイラ エラーが発生する理由がよくわかりません

4

1 に答える 1

6

あなたの考えは正しかったようです (そして斬新な考えでした) が、修正が必要な場所がいくつかありました。これを試してください:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="1.0">

  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes"/>

  <xsl:key name="k1" match="*" use="local-name()"/>

  <xsl:variable name="lookupDoc" select="document('lookup.xml')"/>

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

  <xsl:template match="row/*">
    <xsl:variable name="newName">
      <xsl:apply-templates select="$lookupDoc/lookup">
        <xsl:with-param name="nameToMatch" select="local-name()" />
      </xsl:apply-templates>
    </xsl:variable>
    <xsl:element name="{$newName}">
      <xsl:value-of select="."/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="lookup">
    <xsl:param name="nameToMatch" />
    <xsl:value-of select="string(key('k1', $nameToMatch))"/>
  </xsl:template>
</xsl:stylesheet>

DOM で値key()を見つけるには、その DOM のコンテキストで を使用する必要があり、それが最後のテンプレートの目的です。これをサンプル入力で実行すると、結果は要求された出力になります。$lookupDockey()

<Report>
  <row>
    <fieldA>test1</fieldA>
    <fieldB>test2</fieldB>
    <fieldC>test3</fieldC>
  </row>
  <row>
    <fieldA>test4</fieldA>
    <fieldB>test5</fieldB>
    <fieldC>test6</fieldC>
  </row>
</Report> 

何らかの変更を加えれば、使用しようとしていたアプローチを使用することも可能でした。これは、 DOMfor-each内に入る別の方法だからです。$lookupDoc次の XSLT は、上記のものと同じ結果になるはずであり、元の試みにより似ています。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <xsl:strip-space elements="*"/>
  <xsl:output indent="yes"/>

  <xsl:key name="k1" match="*" use="local-name()"/>

  <xsl:variable name="lookupDoc" select="document('lookup.xml')"/>

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

  <xsl:template match="row/*">
    <xsl:variable name="this" select="." />
    <xsl:variable name="lookup">
      <xsl:for-each select="$lookupDoc">
        <xsl:value-of select="key('k1', local-name($this))"/>
      </xsl:for-each>
    </xsl:variable>
    <xsl:element name="{$lookup}">
      <xsl:value-of select="."/>
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>
于 2013-01-29T05:33:43.257 に答える