0

ノード属性値を一致させたいのですが、同じ値が別のノード属性に表示される場合は、両方をマージする必要があります。たとえば、私はxmlを持っています

<xml>
   <title>
   <metadata>
    <ref cite="ABC" relevance="2"/>
    </metadata>
     <body>
       <para>
            <text>(some text from title)</text>
      </para>
     </body>
    </title>
    <title>
      <metadata>
         <ref cite="ABC" relevance="1"/>
      </metadata>
     <body>
       <para>
            <text>(some more text from title 2)</text>
      </para>
     </body>
    </title>

    <mainbody>
        <targetref cite="ABC"/>
        <text>This is a text</text>  
   </mainbody>
 </xml>

したがって、変換後の出力は次のようになります。したがって、要素 title/metadata/ref の "ABC" を引用し、関連性 (1,2....) で並べ替えると、タイトルのコンテンツが本体のテキスト要素にマージされます。要素「targetref」の引用が要素「ref」の引用と一致する場合

<xml>
  <mainbody>
    <targetref cite="ABC"/>
    <text>This is a text 
        <para><text>(some more text from title 2)</text></para>
       <para><text>(some text from title)</text></para> 
    </text>
   </mainbody>
 </xml> 

ありがとう

4

2 に答える 2

0

これを行う 1 つの方法は、キーを使用して、メタデータの参照値に基づいてタイトルレコードを検索することです。

<xsl:key name="ref" match="title" use="metadata/ref/@cite" />

次に、本体内のテキスト要素に配置されていると仮定すると、そのようにそれらを検索し、同時に並べ替えることができます

<xsl:apply-templates select="key('ref', preceding-sibling::targetref/@cite)/body/para">
   <xsl:sort select="../../metadata/ref/@relevance" />

ここに完全な XSLT があります

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:key name="ref" match="title" use="metadata/ref/@cite" />
   <xsl:template match="title" />

  <xsl:template match="mainbody/text">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
      <xsl:apply-templates select="key('ref', preceding-sibling::targetref/@cite)/body/para" >
         <xsl:sort select="../../metadata/ref/@relevance" />
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

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

サンプル XML に適用すると、次のように出力されます。

<xml>
    <mainbody>
        <targetref cite="ABC"/>
        <text>This is a text
            <para>
                <text>(some more text from title 2)</text>
            </para>
            <para>
                <text>(some text from title)</text>
            </para></text>
    </mainbody>
</xml>
于 2012-05-18T18:47:46.540 に答える
0

ここにあなたが望むことをするいくつかのxsltがあります:

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

<xsl:output omit-xml-declaration="no" method="xml"/>
<xsl:strip-space elements="*"/>

<xsl:template match="mainbody">
<xsl:copy>
        <xsl:copy-of select="targetref"/>
        <xsl:element name="text">
            <xsl:value-of select="."/>
            <xsl:variable name="key" select="targetref/@cite"/>
            <xsl:for-each select="/xml/title[metadata/ref/@cite=$key]">
                <xsl:sort data-type="number" select="metadata/ref/@relevance" order="ascending" />
                <xsl:copy-of select="body/para"/>
            </xsl:for-each>
        </xsl:element>
    </xsl:copy>
</xsl:template>

<xsl:template match="xml/title"/>

<xsl:template match="xml">
    <xsl:copy>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

<xsl:template match="*">
    <xsl:apply-templates/>
</xsl:template>

</xsl:stylesheet>

トリックは、通常のフローでノード xml/title を無視することです。メインボディ タグに注目します。その後、for-each を呼び出して、必要なノードを選択および順序付けし、メインボディ内の必要な場所に情報を書き込みます。選択には、メインボディで指定されたようにフィルタリングするための変数 ($key) が必要です

于 2012-05-18T18:32:24.367 に答える