48

「if」を実行できるxpathの豊富な機能があるようです。ただし、私のエンジンは「そのような機能はありません」と主張し続け、ウェブ上でドキュメントをほとんど見つけられませんでした (疑わしいソースをいくつか見つけましたが、それらの構文は機能しませんでした)。

文字列の末尾から「:」を削除する必要があるため (存在する場合)、これを実行したかったのです。

if (fn:ends-with(//div [@id='head']/text(),': '))
            then (fn:substring-before(//div [@id='head']/text(),': ') )
            else (//div [@id='head']/text())

何かアドバイス?

4

7 に答える 7

65

はい、XPath 1.0 でそれを行う方法があります。

連結(
  substring($s1, 1, number($condition) * string-length($s1)),
  substring($s2, 1, number(not($condition)) * string-length($s2))
)

これは、相互に排他的な 2 つの文字列の連結に依存しています。最初の文字列は、条件が false ( 0 * string-length(...)) の場合は空になり、2 番目の文字列は、条件が true の場合は空になります。これは"Becker's method"と呼ばれ、 Oliver Becker によるものです(元のリンクは現在無効で、Web アーカイブにはコピーがあります)

あなたの場合:

連結(
  部分文字列(
    substring-before(//div[@id='head']/text(), ': '),
    1、
    番号(
      で終わる(//div[@id='head']/text(), ':')
    )
    * string-length(substring-before(//div [@id='head']/text(), ': '))
  )、
  部分文字列(
    //div[@id='head']/text(),
    1、
    数(ではない(
      で終わる(//div[@id='head']/text(), ':')
    )))
    * 文字列の長さ(//div[@id='head']/text())
  )
)

私は以前のすべてを取り除こうとしますが"//"

//div[@id='head']また、複数のノードを返す可能性もあります。
ただ注意してください — 使用//div[@id='head'][1]はより防御的です。

于 2009-06-09T18:14:54.833 に答える
26

W3.orgのXPath 2.0の公式言語仕様では、この言語が実際に if ステートメントをサポートしていることが詳しく説明されています。特に、セクション 3.8 条件式を参照してください。構文形式と説明とともに、次の例を示します。

if ($widget1/unit-cost < $widget2/unit-cost) 
  then $widget1
  else $widget2

これは、式を括弧で囲むべきではないことを示唆しています(そうしないと、構文は正しく見えます)。完全に自信があるわけではありませんが、試してみる価値はあります。したがって、クエリを次のように変更する必要があります。

if (fn:ends-with(//div [@id='head']/text(),': '))
  then fn:substring-before(//div [@id='head']/text(),': ')
  else //div [@id='head']/text()

ifただし、XPath エンジンが実際には言語の特別な構造である関数として解釈しようとしているように見えるため、これで問題が解決するのではないかと強く思っています。

最後に、明らかなことを指摘すると、XPath エンジンが (以前のバージョンではなく) XPath 2.0 を実際にサポートしていることを確認してください。条件式が以前のバージョンの XPath に含まれているとは思えません。

于 2009-06-09T16:28:35.080 に答える
4

pkarat の法則によると、バージョン 1.0 で条件付き XPath を実現できます。

あなたの場合、概念に従ってください:

concat(substring-before(your-xpath[contains(.,':')],':'),your-xpath[not(contains(.,':'))])

これは間違いなく機能します。それがどのように機能するかを見てください。2 つの入力を与える

praba:
karan

最初の入力の場合::条件 true が含まれているため、前の文字列: が出力になります。たとえばpraba、出力です。2番目の条件はfalseになるので問題ありません。

2 番目の入力の場合: 含まれていない:ため、条件が失敗し、2 番目の条件になると、文字列に含まれていない:ため、条件が true になります... したがって、出力karanがスローされます。

最後に、出力はpraba, になりますkaran

于 2010-11-16T03:07:33.713 に答える
3

個人的には、XSLT を使用して XML を変換し、末尾のコロンを削除します。たとえば、次の入力があるとします。

<?xml version="1.0" encoding="UTF-8"?>
<Document>
    <Paragraph>This paragraph ends in a period.</Paragraph>
    <Paragraph>This one ends in a colon:</Paragraph>
    <Paragraph>This one has a : in the middle.</Paragraph>
</Document>

段落の末尾のコロンを取り除きたい場合は、次の XSLT を使用します。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:fn="http://www.w3.org/2005/xpath-functions"
    version="2.0">
    <!-- identity -->
    <xsl:template match="/|@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <!-- strip out colons at the end of paragraphs -->
    <xsl:template match="Paragraph">
        <xsl:choose>
            <!-- if it ends with a : -->
            <xsl:when test="fn:ends-with(.,':')">
                <xsl:copy>
                    <!-- copy everything but the last character -->
                    <xsl:value-of select="substring(., 1, string-length(.)-1)"></xsl:value-of>
                </xsl:copy>
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy>
                    <xsl:apply-templates/>
                </xsl:copy>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet> 
于 2011-02-18T20:02:16.873 に答える
3

代わりに fn:replace(string,pattern,replace) を使用するのはどうですか?

XPATH は XSLT で非常に頻繁に使用されます。そのような状況にあり、XPATH 2.0 を持っていない場合は、次を使用できます。

  <xsl:choose>
    <xsl:when test="condition1">
      condition1-statements
    </xsl:when>
    <xsl:when test="condition2">
      condition2-statements
    </xsl:when>
    <xsl:otherwise>
      otherwise-statements
    </xsl:otherwise>
  </xsl:choose>
于 2009-06-09T16:24:16.513 に答える
2

残念ながら、以前の回答は私には選択肢がなかったので、しばらく調査したところ、次の解決策が見つかりました。

http://blog.alessio.marchetti.name/post/2011/02/12/the-Oliver-Becker-s-XPath-method

特定のノードが存在する場合にテキストを出力するために使用します。4 はテキスト foo の長さです。したがって、より洗練された解決策は、変数を使用することだと思います。

substring('foo',number(not(normalize-space(/elements/the/element/)))*4)
于 2013-03-15T13:41:31.537 に答える