1

私は Schematron を使用して、カスタム スキーマ対応 XML エディター内でインスタンス XML ドキュメントを検証しています (Schematron 検証は単なる XSLT 変換であることに注意してください)。インスタンスには、値にパスを含む要素が含まれる場合があります (簡略化された XPath 式)。このようなパスの例は次のとおりです。

/p:root/p:level-one/r:level-two/r:level-two-leaf

ここで、両方のプレフィックス (p と r) は、インスタンス ドキュメントで定義された名前空間にバインドされます。My Schematron は、パスが指している要素がインスタンス ドキュメントに実際に存在することを確認することで、そのようなパスを検証します。これを行うにはEXSLTに依存しています (私は XSLT1.0 を使用することを余儀なくされています)。より正確にdyn:evaluate()は、要素のテキスト値を評価するために依存しています。それは魅力のように機能します。

しかし、実際には大きな問題が 1 つあります。への呼び出しは、独自の名前空間コンテキストでdyn:evaluate()XPath 式を評価する Schematron XSLT から実行されます。これは、これが適切に機能するためには、インスタンス ドキュメントと Schematron XSLT の両方がまったく同じ接頭辞 → 名前空間を使用する必要があることを意味します。バインディング。スキーマで指定されている同じ名前空間に同じプレフィックスを使用するようユーザーに強制することはできません...これはばかげた要件です (ただし、少なくとも同じ名前空間が両方で使用されることが保証されています)。Schematron は常にインスタンスの検証が行われる前に生成されますが、これはパフォーマンス上の理由から一度だけ行われます。私が持っている唯一のオプションは、インスタンスからのパスを何らかの方法で前処理し、「インスタンス パス」から「XSLT パス」への何らかの変換を行うことです。私は XSLT が初めてで、どうすればこれを達成できるかわかりません。

このようなテキスト値を、XSLT の名前空間コンテキストで必要とされるものに変換するにはどうすればよいでしょうか? これは可能ですか?私は現在、各検証呼び出しの前に XSLT のメモリ内修正 (これはすべて Java 内で行われます) について考えています。プレフィックスの名前を変更して、新しい名前空間属性をバインドまたは注入するインスタンスと一致するようにします。しかし、これはプレフィックス名の衝突につながる可能性があり、検証のパフォーマンスにどのように影響するかはわかりません。これは、他の人も (Schematron または を使用しているときに) 遭遇したに違いないものであると想定しているため、私はどんな提案にもオープンですdyn:evaluate()

編集:私がやろうとしていることの明確化は、これから続きます。

エディターでユーザーが編集している XML インスタンス ファイルがあります。このようなファイルの例は次のとおりです。

<?xml version="1.0" encoding="utf-8"?>
<config xmlns="http://example.com/ns/config"
         xmlns:cfg="http://example.com/ns/config"
         xmlns:ns1="http://example.com/ns/custom-01"
         xmlns:ns2="http://example.com/ns/custom-02">
  <ns1:some-element>/cfg:config/ns1:other-element/ns2:nested-element</ns1:some-element>
  <ns1:other-element>
    <ns2:nested-element>some value</ns2:nested-element>
  </ns1:other-element>
</config>

このようなドキュメントは、基本的に XSLT 変換であるスキーマトロン検証を通過します。パスが同じドキュメント内の既存の要素を参照している場合にのみ、有効であると宣言されns1:some-elementます (したがって、上記の例は有効です)。

スキーマトロン XSLT は次のようになります (大幅に簡略化されていることに注意してください)。

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!--This XSLT was automatically generated from a Schematron schema.-->
<xsl:stylesheet xmlns:iso="http://purl.oclc.org/dsdl/schematron"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:dyn="http://exslt.org/dynamic"
                xmlns:exsl="http://exslt.org/common"
                xmlns:sch="http://www.ascc.net/xml/schematron"
                xmlns:cfg="http://example.com/ns/config"
                xmlns:cust1="http://example.com/ns/custom-01"
                xmlns:cust2="http://example.com/ns/custom-02"
                extension-element-prefixes="dyn exsl"
                version="1.0">

<!-- other templates -->

<xsl:template match="/cfg:config/cust1:some-element">
    <xsl:choose>
        <xsl:when test="dyn:evaluate(.)">
            <!-- do stuff -->
        <xsl:when>
    </xsl:choose>
</xsl:template>

<!-- other templates -->

</xsl:stylesheet>

これで問題が説明できると確信しています。への呼び出しdyn:evaluate(.)は、XPath 式を評価しようとし/cfg:config/ns1:other-element/ns2:nested-elementます。これは、変換の観点からバインドされていないプレフィックスを使用します (したがって、常に false に評価されます)。

問題は、これらの XPath 式が実際に変換内で意味を持つように変換するにはどうすればよいかということでした。

4

1 に答える 1