1

私は次のテンプレートを持っています:

<xsl:template match="footnote">
    <xsl:variable name = "string">
        <xsl:value-of select="."/>
    </xsl:variable>
    <xsl:variable name = "bool">
        <xsl:if test="$string = preceding-sibling::node()/$string">
            <xsl:text>false</xsl:test>
        </xsl:if>
    </xsl:variable>
    <xsl:if test="$bool != 'false'">
        <!-- DO STUFF -->
    </xsl:if>
</xsl:template>

現在のノードの$string変数をチェックし、以前のすべての脚注ノードと照合して、同じ$string変数があるかどうかを確認しようとしています。前の兄弟のいずれとも一致しない場合は、何かを実行する必要があります。それ以外の場合は、何も実行しないでください。

私が持っているコードでは、脚注ノードがまだ作成されていない場合でも、テスト "$ string = previous-sibling :: node()/$string"は常にtrueと評価されます。

誰かが私を助けることができますか?以前のすべての兄弟の変数と比較する式を作成するのに苦労しています。

編集:サンプルXML:

<xml>
<footnote>Footnote 1</footnote>
<footnote>Footnote 2</footnote>
<footnote>Footnote 1</footnote>
<footnote>Footnote 1</footnote>
<footnore>Footnote 3</footenote>
</xml>

私はそれを次のように変換しようとしています:

<xml>
<footnote>Footnote 1</footnote>
<footnote>Footnote 2</footnote>
<footnote>Footnore 3</footnore>
</xml
4

5 に答える 5

5

上手。出力XMLを投稿すると、より明確になります。そこにあなたは解決策を持って行きます:

サンプルXML:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <footnote>Matching</footnote>
  <footnote>Example1</footnote>
  <footnote>Matching</footnote>
  <footnote>Example2</footnote>
  <footnote>Example3</footnote>
</root>

そしてXSL:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
  <xsl:template match="footnote[.=preceding-sibling::footnote/.]"/>
</xsl:stylesheet>

結果:

<?xml version="1.0" encoding="utf-8"?>
<xml>
  <footnote>Matching</footnote>
  <footnote>Example1</footnote>
  <footnote>Example2</footnote>
  <footnote>Example3</footnote>
</xml>
于 2012-12-07T14:47:46.067 に答える
2

現在の脚注の値をtext()前の脚注と比較text()'sして一意性を確認したい場合は、 preceding-sibling::node()'s text():を確認するだけです。

<xsl:if test="$string = preceding-sibling::node()/text()">

例えば

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0"
                >
    <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" indent="yes" />

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

    <xsl:template match="footnote">
        <xsl:variable name = "string">
            <xsl:value-of select="./text()"/>
        </xsl:variable>
        <xsl:variable name = "bool">
            <xsl:if test="$string = preceding-sibling::node()/text()">
                <xsl:text>false</xsl:text>
            </xsl:if>
        </xsl:variable>
        <xsl:if test="$bool != 'false'">
            <xsl:copy-of select="."></xsl:copy-of>
        </xsl:if>
    </xsl:template>

</xsl:stylesheet>

入力を回します:

<xml>
    <footnote>
        someVal
    </footnote>
    <footnote>
        anotherVal
    </footnote>
    <footnote>
        anotherVal
    </footnote>
    <footnote>
        newVal
    </footnote>
</xml>

の中へ:

<xml>
  <footnote>
        someVal
    </footnote>
  <footnote>
        anotherVal
    </footnote>
  <footnote>
        newVal
    </footnote>
</xml>

要素内のグループを識別することを目的としている場合は、Muenchianのグループ化も確認する必要があります。

于 2012-12-07T14:54:20.693 に答える
1

あなたが使うことができます

<xsl:template match="footnote[not(. = preceding-sibling::footnote)]">

指定された脚注文字列の最初のインスタンスに対してのみ起動するテンプレートを作成します。このノードの文字列値が前の兄弟のいずれか. = preceding-sibling::footnoteの文字列値と同じである場合はtrueであるため、すべての兄弟と異なる場合はtrueになります。not(....)

ただし、大きなドキュメントの場合、これはかなり非効率的です(脚注要素の数が2次式)。<xsl:for-each-group>(XSLT 2.0)またはMuenchian Grouping(XSLT 1.0)を使用して、footnote要素を文字列値でグループ化し、各グループから最初の要素を抽出することをお勧めします。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:key name="fn" match="footnote" use="." />

  <!-- Ignore all but the first footnote for a given value -->
  <xsl:template match="footnote[generate-id() != generate-id(key('fn', .)[1])]" />

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

</xsl:stylesheet>
于 2012-12-07T14:54:38.030 に答える
0

XSLT 2.0には、distinct-values関数があります。

<xsl:for-each select="distinct-values(footnote)">
    <footnote><xsl:value-of select="."/></footnote>
</xsl:for-each>
于 2012-12-09T22:49:34.710 に答える
0

<xsl:template match="footnote">

    <xsl:variable name = "string">
      <xsl:value-of select="./text()"/>
    </xsl:variable>
    <xsl:variable name = "bool">
      <xsl:if test="$string != preceding-sibling::node()/text()">
        <xsl:text>false</xsl:text>
    </xsl:if>
    </xsl:variable>
    <xsl:if test="$bool != 'false'">
        true
    </xsl:if>
  <xsl:if test="$bool = 'false'">
    false
  </xsl:if>
  </xsl:template>

于 2012-12-07T15:05:25.763 に答える