2017-02-07 10 views
0

私はSaxon HE 9.7.0を使ってXSLT 2.0を変換しています。私のファイルでは、サブツリーを選択し、それを変数に入れて後で使用しようとしています。変数に格納されているサブツリーにアクセスすると例外が発生する

入力XML:

<xsl:variable name="selectedDocument"> 
    <xsl:variable name="lowestDocumentIndex" select="min($documents/document/orderIndex)" /> 
    <xsl:value-of select="$documents/documents[index=$lowestDocumentIndex]" /> 
</xsl:variable> 

<!-- Now later on, I want to use the contents of the selected document: --> 
<xsl:value-of select="$selectedDocument/code" /> 

<?xml version="1.0"?> 
<documents> 
    <document> 
     <code>009190</code> 
     <index>3</index> 
    </document> 
    <document> 
     <code>583876</code> 
     <index>1</index> 
    </document> 
    <document> 
     <code>277410</code> 
     <index>2</index> 
    </document> 
</documents> 

が今私のXSLTで私が最も低いインデックスを持つドキュメントを選択し、後でそのコードを使用する場合は、(変数 documentsはルートツリーが含まれています)これにより、次のようなパーサの例外が発生します。

Caused by: java.lang.RuntimeException: Internal error evaluating template rule at line 23 in module 
    at net.sf.saxon.expr.instruct.TemplateRule.applyLeavingTail(TemplateRule.java:366) 
    at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:456) 
    at net.sf.saxon.Controller.transformDocument(Controller.java:2291) 
    at net.sf.saxon.Controller.transform(Controller.java:1863) 
    at net.sf.saxon.s9api.XsltTransformer.transform(XsltTransformer.java:579) 
    at net.sf.saxon.jaxp.TransformerImpl.transform(TransformerImpl.java:185) 
    at de.haba.genex.exp.core.model.nodes.XSLTTransformationNode.lambda$process$0(XSLTTransformationNode.java:146) 
    ... 40 more 
Caused by: java.lang.ClassCastException: net.sf.saxon.value.UntypedAtomicValue cannot be cast to net.sf.saxon.om.NodeInfo 
    at net.sf.saxon.expr.SimpleStepExpression.iterate(SimpleStepExpression.java:108) 
    at net.sf.saxon.expr.Atomizer.iterate(Atomizer.java:293) 
    at net.sf.saxon.expr.AtomicSequenceConverter.iterate(AtomicSequenceConverter.java:249) 
    at net.sf.saxon.expr.SystemFunctionCall.evaluateArguments(SystemFunctionCall.java:360) 
    at net.sf.saxon.expr.FunctionCall.iterate(FunctionCall.java:544) 
    at net.sf.saxon.expr.Expression.evaluateItem(Expression.java:763) 
    at net.sf.saxon.expr.Expression.evaluateAsString(Expression.java:859) 
    at net.sf.saxon.expr.instruct.SimpleNodeConstructor.processLeavingTail(SimpleNodeConstructor.java:186) 
    at net.sf.saxon.expr.instruct.ValueOf.processLeavingTail(ValueOf.java:283) 
    at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:653) 
    at net.sf.saxon.expr.LetExpression.processLeavingTail(LetExpression.java:711) 
    at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:653) 
    at net.sf.saxon.expr.LetExpression.processLeavingTail(LetExpression.java:711) 
    at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:653) 
    at net.sf.saxon.expr.LetExpression.processLeavingTail(LetExpression.java:711) 
    at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:653) 
    at net.sf.saxon.expr.instruct.NamedTemplate.expand(NamedTemplate.java:257) 
    at net.sf.saxon.expr.instruct.CallTemplate.process(CallTemplate.java:356) 
    at net.sf.saxon.expr.LetExpression.process(LetExpression.java:568) 
    at net.sf.saxon.expr.instruct.ForEach.processLeavingTail(ForEach.java:453) 
    at net.sf.saxon.expr.LetExpression.processLeavingTail(LetExpression.java:711) 
    at net.sf.saxon.expr.instruct.Choose.processLeavingTail(Choose.java:835) 
    at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:149) 
    at net.sf.saxon.expr.LetExpression.process(LetExpression.java:568) 
    at net.sf.saxon.expr.instruct.ForEach.processLeavingTail(ForEach.java:453) 
    at net.sf.saxon.expr.LetExpression.processLeavingTail(LetExpression.java:711) 
    at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:653) 
    at net.sf.saxon.expr.instruct.TemplateRule.applyLeavingTail(TemplateRule.java:353) 
    ... 46 more 

XSLT 2.0ではRTFを保存しなくても、実際の一時的なツリーは保持していますが、これは機能しませんか?

これは私がやろうとしていることのちょっとした例です。私は実際には<xsl:variable>の中に<xsl:choose>を持っていて、文書の構造はもっと複雑ですが、アイデアは同じでなければなりません。


EDITは:私の問題は、私が最初に別のテンプレートに文書のリストを渡すことに関係しているようです。答えに書かれたようxsl:copy-ofを使用するには、動作しているようですが、私はやるときは、次のではない:

間違って起こっているの

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

    <xsl:template match="/"> 
     <xsl:call-template name="processDocuments"> 
      <xsl:with-param name="docs" select="documents" /> 
     </xsl:call-template> 
    </xsl:template> 

    <xsl:template name="processDocuments"> 
     <xsl:param name="docs" /> 

     <xsl:variable name="selectedDocument"> 
      <xsl:variable name="lowestDocumentIndex" select="min(doc/document/index)" /> 
      <xsl:copy-of select="doc/document[index=$lowestDocumentIndex]" /> 
     </xsl:variable> 

     <xsl:value-of select="$selectedDocument/document/code" /> 
    </xsl:template> 

</xsl:transform> 

どれより多くのアイデア(http://xsltransform.net/ejivdHL/2でそれを試してみてください)?私はこのために2番目のテンプレートを使用する必要があります。これは、さまざまなノードに対してテンプレートを複数回使用するためです。

答えて

0

ノードのコピーを保存するには、<xsl:value-of select="$documents/documents[index=$lowestDocumentIndex]" />の代わりに<xsl:copy-of select="$documents/documents[index=$lowestDocumentIndex]" />が必要です。 value-ofは、選択したノードの文字列値を含むテキストノードを作成します。私はhttp://xsltransform.net/ejivdHL583876を出力

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

    <xsl:template match="/"> 
     <xsl:variable name="selectedDocument"> 
      <xsl:variable name="lowestDocumentIndex" select="min(documents/document/index)" /> 
      <xsl:copy-of select="documents/document[index=$lowestDocumentIndex]" /> 
     </xsl:variable> 

     <!-- Now later on, I want to use the contents of the selected document: --> 
     <xsl:value-of select="$selectedDocument/document/code" /> 
    </xsl:template> 

</xsl:transform> 

を得ることを固定する際

さらに、いくつかの参照/パスは、一致していないようです。 http://xsltransform.net/ejivdHL/1

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

    <xsl:template match="/"> 
     <xsl:variable name="lowestDocumentIndex" select="min(documents/document/index)" /> 
     <xsl:variable name="selectedDocument" select="documents/document[index=$lowestDocumentIndex]" /> 


     <!-- Now later on, I want to use the contents of the selected document: --> 
     <xsl:value-of select="$selectedDocument/code" /> 
    </xsl:template> 

</xsl:transform> 

オンライン:一時的なツリーを作成する必要は本当にありません

は、単に元の入力要素を選択することができます。

+0

ご返信ありがとうございます - 最初の例はうまくいきますが、私の問題は深いと思われます。私はこの質問にもっと詳細を加えました。あなたはおそらく考えを持っていますか? – maxdev

+0

http://xsltransform.net/ejivdHL/3の訂正を見てください。パラメータ 'docs'を' $ docs'として参照する必要があり、 'doc'ではなく' docs'で参照する必要があります。 –

+0

ああ、このように、この例ではうまくいきます。私はまだ私のXSLTで別の問題がありますが、私はもう少し検索する必要があります。 – maxdev

0

使用:

<xsl:variable name="lowestDocumentIndex" select="min($documents/document/index)" /> 
<xsl:variable name="selectedDocument" select="$documents/document[index=$lowestDocumentIndex]" /> 

コード内の<xsl:value-of>は、選択されたノード(連結テキストノード)のないノード自体の抽出と思われます。

ところで:コードには$documents/documentsが含まれています。 最後のsは削除する必要があります。

+0

最後の文章で書いたように、 ''を使用する必要があるときは、これは機能しません – maxdev

0

「Saxon internal error」というスタックトレースは、Saxonバグであることを意味します。既に知っているかもしれないし、修正したかもしれないかもしれないが、バグは全く同じかもしれない。 saxonica.plan.ioのバグトラッカーにSaxonのバグを報告するのが最善です。スタイルシートとソースドキュメント、および問題を再現するための設定パラメータのようなその他の必要な情報が必要となるでしょう。

ただ、予備的な分析を少し与えるために、キーの失敗は、それが実行時エラーだと、我々は何かである「シンプルなステップ式」を評価していることを教えてくれる

java.lang.ClassCastException: net.sf.saxon.value.UntypedAtomicValue cannot be cast to net.sf.saxon.om.NodeInfo 
at net.sf.saxon.expr.SimpleStepExpression.iterate(SimpleStepExpression.java:108) 

です$ lhs/child :: Xのように.LHSはシングルトンを返す式で、RHSは軸式です。行番号から最新のメンテナンスリリースを実行していないことがわかります(NodeInfoへのキャストが110行目になったためです)。 ClassCastExceptionは、式のLHSがノードであると予想されるため実際には原子値であるため、以前にこれを検出したはずの型チェックで何かが間違っていることを意味します。コードに誤りがあり、正しく取り上げて診断することができない可能性があります。

残念ながら、スタックトレースは、スタイルシート内のどのコードがエラー発生時に実行されているかを正確に示すための情報を提供していません。そのため、私たちはreproが必要なので、デバッグ環境でそれを実行し、障害の発生時にそれをキャッチすることができます。

これは、(a)最新のザクセンメンテナンスリリース(現在は9.7.0.14ですが、このスペースを見てください)で試してください。(b)再びクラッシュする場合は、saxonica.plan .io。ありがとう!

関連する問題