1

私は 2 つの XML ドキュメントを扱っており、変数が一致する場合に一方のドキュメントから他方のドキュメントに値を取得しようとしています。最初の XML ドキュメントは、次のような形式の変換されたスプレッドシートです。

<Doc1>
    <row>
      <cell>VA15</cell>
      <cell>wr23</cell>
    </row>
    <row>
      <cell>VA45</cell>
      <cell>wr27</cell>
    </row>        <row>
      <cell>VA78</cell>
      <cell>wr24</cell>
    </row>
</Doc1>

id2 番目の XML ドキュメントは、スプレッドシートの一部と一致する要素が含まれる長いドキュメントです。

<Doc2>
 <p> text text text
  <id>wr23</id>
 </p>
</Doc2>

xslt 変換を使用して、要素が doc1idの a の値と一致するかどうかをテストして、前の の値を取得しようとしています。この場合、xslt 変換で「VA15」を出力したいと思います。次のコードのさまざまな順列を試してみましたが、成功しませんでした。誰かアイデアはありますか?cellcell

<xsl:for-each select="document('Doc1.xml')//row">
   <xsl:if test="/cell=//id'">
     <xsl:value-of select="/preceding-sibling::cell"/>
   </xsl:if>
</xsl:for-each>
4

2 に答える 2

1

Dimitreの回答に基づいて、この「IDREFを検索する」パターンをkey()(高速検索用に)およびを使用して別のテンプレートに抽象化できcall-templateます。

id-lookup.xsl

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="id-lookup-doc">Doc1.xml</xsl:param>
<xsl:variable name="id-to-value-doc" select="document($id-lookup-doc)"/>

<xsl:key name="value-for-id"
    match="/Doc1/row/cell[1]"
    use="../cell[2]" />


<xsl:template name="value-for-id">
    <xsl:param name="id"/>
    <!-- for-each is just to change the context
         to limit results from key() to the lookup document -->
    <xsl:for-each select="$id-to-value-doc">
        <xsl:value-of select="key('value-for-id', $id)"/>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

replace-id-with-value.xsl

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

<xsl:import href="id-lookup.xsl"/>

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

<xsl:template match="id">
    <val>
        <xsl:apply-templates select="@*"/>
        <xsl:call-template name="value-for-id">
            <xsl:with-param name="id" select="text()"/>
        </xsl:call-template>
    </val>
</xsl:template>

</xsl:stylesheet>

これを xslt プロセッサで実行すると、すべての<id>要素が置き換えられたドキュメントと<val>対応する値が得られます。

を使用するxsltprocと、次のように実行できます。

xsltproc id-with-value.xsl Doc2.xml myOtherDoc.xml

xslt パラメータを使用してルックアップ ドキュメントを変更することもできます。

xsltproc --stringparam id-lookup-doc MyOtherSetOfIdsAndValues.xml id-with-value.xsl Doc2.xml

どの XSLT プロセッサを使用していても、テンプレート パラメータを指定する何らかの方法があります。

于 2012-12-17T21:24:15.320 に答える
0
<xsl:for-each select="document('Doc1.xml')//row">
   <xsl:if test="/cell=//id'">
     <xsl:value-of select="/preceding-sibling::cell"/>
   </xsl:if>
</xsl:for-each>

いくつかの問題:

  1. 2つのドキュメントのいずれにも、という名前の最上位要素cellがありません。絶対式の代わりに、相対式を使用する必要があります。

....。

cell = //id

  preceding-sibling::cell

ドキュメントノードには兄弟がないためです。

.2。名前付きの要素を持つドキュメントには、という名前の要素cellがありませんid。XPath式が複数のドキュメントを参照する場合、1つを除くすべてのドキュメントを明示的に参照する必要があります。すべての修正を加えると、コードは次のようになります。

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

  <xsl:for-each select="document('Doc1.xml')//row">
     <xsl:if test="cell=$vthisDoc//id'">
       <xsl:value-of select="preceding-sibling::cell"/>
     </xsl:if>
  </xsl:for-each>

最後に、これはすべてすぐに次のように書くことができます。

<xsl:copy-of select=
 "document('Doc1.xml')//row[cell=$vthisDoc//id]/preceding-sibling::cell[1]/text()"/>
于 2012-12-17T18:56:46.477 に答える