2

次の問題が発生しました。コード例を参照してください。

<xsl:if test="/Document/test/id">
  <TEST1>
     <xsl:value-of select="/Document/test/id"/>
   </TEST1>
</xsl:if>

同じコードがたくさんある巨大なxsltスクリプトがあります。関数を作成したかったのですが、いつもエラーが発生しました。私はそれがこの問題を解決するための正しい解決策であるかどうかを自問していました。

コードをより保守しやすくするために、次のようなものを使用したいと思います。方法がわからないため、これはxslt構文ではありませんが、私が探しているものを理解するためのものです。

...
<xsl:something "TEST1", "/Document/test/id1" />
<xsl:something "TEST2", "/Document/test/id2" />
...

これを解決する方法はわかりませんが、コードは読みやすく、保守しやすくなります:-(アドバイスは大歓迎です...

よろしくダーク

4

2 に答える 2

2

これがあなたの目的に最も近いと思います:

<xsl:stylesheet version="2.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:f="custom-functions" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <xsl:template match="/">
    <CONTENT>
      <xsl:sequence select="f:rename('TEST1', /Document/test/id1)"/>
      <xsl:sequence select="f:rename('TEST2', /Document/test/id2)"/>
    </CONTENT>
  </xsl:template>

  <xsl:function name="f:rename">
    <xsl:param name="name" as="xs:string"/>
    <xsl:param name="toWrap" />

    <xsl:if test="$toWrap">
      <xsl:element name="{$name}">
        <xsl:value-of select="$toWrap"/>
      </xsl:element>
    </xsl:if>
  </xsl:function>
</xsl:stylesheet>

これが次の入力で実行される場合:

<Document>
  <test>
    <id1>Hello!</id1>
    <id2>Hello again!</id2>
  </test>
</Document>

生成される出力は次のとおりです。

<CONTENT>
   <TEST1>Hello!</TEST1>
   <TEST2>Hello again!</TEST2>
</CONTENT>

これはもう少し冗長ですが、XSLT 1.0 と互換性があります。

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

  <xsl:template match="/">
    <CONTENT>
      <xsl:apply-templates select="/Document/test/id1" mode="rename">
        <xsl:with-param name="name" select="'TEST1'" />
      </xsl:apply-templates>
      <xsl:apply-templates select="/Document/test/id2" mode="rename">
        <xsl:with-param name="name" select="'TEST2'" />
      </xsl:apply-templates>
    </CONTENT>
  </xsl:template>

  <xsl:template match="@* | node()" mode="rename">
    <xsl:param name="name" />
    <xsl:element name="{$name}">
      <xsl:value-of select="." />
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

上記のサンプル XML で実行すると、再び同じ出力が生成されます。

于 2013-03-02T17:27:08.607 に答える
2

この変換:

<xsl:stylesheet version="2.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:my="my:my" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <xsl:variable name="vDoc" select="/"/>

 <xsl:template match="/">
     <xsl:sequence select="my:test(xs:QName('Test1'), /*/test/id1/string())"/>
     <xsl:sequence select="my:test(xs:QName('Test2'), /*/test/id2/string())"/>
     <xsl:sequence select="my:test(xs:QName('Test3'), /*/test/id3/string())"/>
     <xsl:sequence select="my:test(xs:QName('Test4'), /*/test/id4/string())"/>
 </xsl:template>

 <xsl:function name="my:test">
   <xsl:param name="pName" as="xs:QName"/>
   <xsl:param name="pToPresent" as="item()?"/>

   <xsl:if test="$pToPresent">
     <xsl:element name="{$pName}">
             <xsl:sequence select="$pToPresent"/>
     </xsl:element>
   </xsl:if>
 </xsl:function>
</xsl:stylesheet>

次の XML ドキュメントに適用した場合:

<Document>
 <test>
  <id1>Some Id1</id1>
 </test>
 <test>
  <id2>Some Id2</id2>
 </test>
 <test>
  <id4>Some Id4</id4>
 </test>
</Document>

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

<Test1>Some Id1</Test1>
<Test2>Some Id2</Test2>
<Test4>Some Id4</Test4>

注意してください:

  1. の最初の引数はmy:test()type で宣言されています。これにより、命令の属性の値が常に有効な名前xs:QNameであることが保証されます。namexsl:element

  2. の 2 番目の引数はmy:test()、 type の非常に大まかに宣言されてitem()?います。これにより、任意のタイプのアイテム (文字列、ノード、要素、または ...) を提供する自由が与えられ、提供されたものが正確に「そのまま」再現されます。

于 2013-03-02T16:25:06.663 に答える