1

こんにちは、saxon でも eclipse を使用してこの xml データを変換しようとしていますが、saxon xslt2.0 で変換しようとすると、メモリ エラーが発生します。デフォルトの eclipse xslt 変換で実行すると、変更は 500M です。出力はエラーなしで実行され、ノードと 1 つの URL が正しく変更されたが、ノードではなく、他のデータがない xml が返されます。

これはxslファイルです:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
    <xsl:variable name="replacedURL">
        <xsl:call-template name="string-replace-all">
            <xsl:with-param name="text" select="/products/product/buy_link/text()"/>
            <xsl:with-param name="replace" select="'[[PARTNERID]]'"/>
            <xsl:with-param name="by" select="'12345'"/>
        </xsl:call-template>
    </xsl:variable>
    <xsl:value-of select="$replacedURL"/>
   </xsl:template>
   <xsl:template name="string-replace-all">
    <xsl:param name="text"/>
    <xsl:param name="replace"/>
    <xsl:param name="by"/>
    <xsl:choose>
        <xsl:when test="contains($text, $replace)">
            <xsl:value-of select="substring-before($text,$replace)"/>
            <xsl:value-of select="$by"/>
            <xsl:call-template name="string-replace-all">
                <xsl:with-param name="text" select="substring-after($text,$replace)"/>
                <xsl:with-param name="replace" select="$replace"/>
                <xsl:with-param name="by" select="$by"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$text"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>
</xsl:stylesheet>
4

2 に答える 2

1

プリミティブ再帰変換は、多くの場合、スタック オーバーフロー例外で終了する可能性があります(通常、N は約 1000 である N 回のネストされた再帰呼び出しで)。

XSLT 2.0 では、最も効率的な RegEx ベースの XPath 2.0 関数を使用しますreplace()

ここに小さな例があります:

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

 <xsl:template match="/*">
     <t><xsl:sequence select=
      "replace(., '\[\[PARTNERID\]\]', '12345')"/>
      </t>
 </xsl:template>
</xsl:stylesheet>

この変換が次の XML ドキュメントに適用される場合:

<t>dadasdas [[PARTNERID]] sfsdfsffs [[PARTNERID]]  sdsdfffsdf [[PARTNERID]]</t>

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

<t>dadasdas 12345 sfsdfsffs 12345  sdsdfffsdf 12345</t>

説明:

RegEx 処理は通常のオートマトンを使用します。これは、スタックの各「プッシュ」でより多くのメモリを消費するスタックベースの処理とは異なり、(オートマトン用に) 限られた量のメモリしか必要としません。

于 2012-07-26T22:52:16.417 に答える
1

一部のノードに特定の変更を加えた以外は、結果の XML を入力と同じにしたい場合は、次のようにスタイルシートを作成するのが最も簡単な方法です。

  1. 恒等変換を使用して 、入力をそのまま出力にコピーしてから、
  2. 変更するノードのテンプレートを選択的にオーバーライドします。

この場合、入力 XML をそのまま出力にコピーし、次の/products/product/buy_link/text()ように XPath 式に一致するノードでのみ文字列置換を適用します。

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

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

  <xsl:template match="/products/product/buy_link/text()">
    <xsl:variable name="replacedURL">
      <xsl:call-template name="string-replace-all">
        <xsl:with-param name="text" select="."/>
        <xsl:with-param name="replace" select="'[[PARTNERID]]'"/>
        <xsl:with-param name="by" select="'12345'"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:value-of select="$replacedURL"/>
  </xsl:template>

  <xsl:template name="string-replace-all">
    <xsl:param name="text"/>
    <xsl:param name="replace"/>
    <xsl:param name="by"/>
    <xsl:choose>
      <xsl:when test="contains($text, $replace)">
        <xsl:value-of select="substring-before($text,$replace)"/>
        <xsl:value-of select="$by"/>
        <xsl:call-template name="string-replace-all">
          <xsl:with-param name="text" select="substring-after($text,$replace)"/>
          <xsl:with-param name="replace" select="$replace"/>
          <xsl:with-param name="by" select="$by"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$text"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>
于 2012-08-01T14:29:02.790 に答える