お世話になります。
現在、XPathに関するプログラムを制作しています。
入力されたXPathを解析し、解析した内容に応じて特定の処理をさせるというものなのですが、text() 関数の解析で躓いています。

text()="value"

ここまではわかります。

text()='value1"value2\value3'

上のケースでは、どのように記述すればいいのでしょうか?
シングルコーテーションで括るという解では、シングルコーテーションとダブルコーテーションが混在している場合に対応できません。
そのプログラムではクオート文字をダブルコーテーションに限定しているので、ダブルコーテーションのエスケープ方法を探しています。
現在はバックスラッシュ(\)によるエスケープ処理で対応しています。

text()="value1\"value2\\value3"

しかし、Firefox拡張「XPath Checker」で調べるとバックスラッシュによるエスケープ処理は働いていないため、
この方法は正しくない気がしています。
プログラムとしては問題なく動作していますが、XPath記法に沿っていないのは落ち着きません。

何かヒントとなる情報はないでしょうか?

このQ&Aに関連する最新のQ&A

A 回答 (1件)

一つのリテラルで表記するのは無理だと思います。

…と思ったんだけどなあ

まず,XPath 1.0規格で一つのリテラルで表現する事はできないようです。
http://www.w3.org/TR/xpath#NT-Literal

>そのプログラムではクオート文字をダブルコーテーションに限定しているので、
これがなく,一つのリテラルでなくて良い(計算結果でも良い)なら
回避策として
concat("AB'C",'DE"F')
とかどうにでもなるとは思うんですが。

念のためにXPath 2.0の構文を調べてみたら
http://www.w3.org/TR/xpath20/#id-literals
EscapeQuotやEscapeAposなんてものがあるので
多分"abc""def"というような表記が可能なようです。

#XPath 1.0同様にあとはXQuery 1.0 and XPath 2.0 Functionsの
http://www.w3.org/TR/xpath-functions/#func-codep …
で計算してごまかすぐらい?

#実際にアドオンをインストールしていないのでFirefox AddonsがXPath 2.0に対応しているかは判りません。
#本題とは関係ないけど,プログラムのユーザーが
文字列を入力してそれが含まれるような要素を探すようなプログラムなら,XPath Injectionとか怖いから
文字列をXPath Expressionに直接つながないで,要素加えてからやるかな。
    • good
    • 1
この回答へのお礼

XPath1.0仕様上ではエスケープ手段が用意されていないのですね。
あの後、仕様書に行き着きましたが理解が足りないだけかも、との思いから先に進めずにいました。

> EscapeQuotやEscapeAposなんてものがあるので
ありがとうございます!
この方法でエスケープするようにしてみます。
(残念ながら、「XPath Checker」では機能しませんでした。XPath2.0準拠の動作ではないようです。)

> #本題とは関係ないけど,プログラムのユーザーが
> 文字列を入力してそれが含まれるような要素を探すようなプログラムなら
逆にユーザが入力したXPathに対応したノードを作成します。(XPathの文法は借りましたが、動作は逆です)
例えば、以下のように。

入力: p[@class="xpath"][text()="XPathですよ"]
出力: <p class="xpath">XPathですよ</p>

お礼日時:2009/05/13 23:09

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

Q特殊記号が勝手にエスケープされてしまう

Windows2000 ServerにおいてVBScriptとMicrosoft.XMLDOMを用いてASPスクリプトを作成しています。

XMLで特殊文字<,>,",',&を扱う際には&lt;,&gt;,&quot;,&apos;に置換しなくてはならない事はわかったんですが、
実際にReplaceすると例えば&lt;が&amp;lt;になってしまいます。
置換する順番を変えてもこうなるのでおかしいと重い、&amp;への置換を止めてもです。
しかもこれは読み出すと何事も無かったかのように&amp;lt;が&lt;へと戻っています。

試しに置換を全く行わない状態で
「テスト&'>"」という文字列を保存してみると、
保存先ファイルの中では「テスト&amp;'&gt;&quot;」という状態になっていました。

恐らく&,<,>,"が勝手に置換され、読み出される時には元に戻す処理が行われていると思うんですが、これがどの部分で行われているのかがよくわかりません。
JavaScriptで読み出した際にも同様に復元されていたようなので、MSXMLの仕様なのかなと思うんですが、それを裏付ける資料を見つける事もできませんでした。

XMLにおける特殊記号の扱いについて書いているサイトにも記述が見つからなかったので、もしかしたら凄く基本的な事だったりおかしな質問だったりするのかもしれませんが、ご存知の方がいらっしゃいましたら是非ご教授願いたいです。
参考URLだけでも良いですのでどうかよろしくお願いします。

Windows2000 ServerにおいてVBScriptとMicrosoft.XMLDOMを用いてASPスクリプトを作成しています。

XMLで特殊文字<,>,",',&を扱う際には&lt;,&gt;,&quot;,&apos;に置換しなくてはならない事はわかったんですが、
実際にReplaceすると例えば&lt;が&amp;lt;になってしまいます。
置換する順番を変えてもこうなるのでおかしいと重い、&amp;への置換を止めてもです。
しかもこれは読み出すと何事も無かったかのように&amp;lt;が&lt;へと戻っています。

試しに置換を全く行わない状態で
「テスト&'>"」という...続きを読む

Aベストアンサー

#2>node.attributes.item(0).nodeValue = "test>"
node.attributes.item(0).nodeValue = "test<"
の間違いですね

>MSXMLの仕様なのかなと
MSXMLのリファレンスで

According to the W3C DOM specification, an XML parser can completely expand entity references into entities before the structure model is passed to the DOM. When these entity references are expanded, the document tree does not contain any entity references.

When Microsoft&reg; XML Core Services (MSXML) validates the XML document, it expands external entities (except binary entities). The nodes representing the expanded entity are available as read-only children of the entity reference. The Microsoft implementation does not expand these entities when it is not validating.

とあるので、仕様かと思います。
(英語力が低いので、何ですが、W3C DOM の求めるところで、XMLパーサーは、DOMに変換するにあたってエンティティの展開をするべきということかな?、なんにしても、XMLパーサーとしては、変換するか、エラーにするかしないといけませんが、エラーにしてたら使い勝手の悪いものになると思います。)
ちなみに、
xmlDoc.createEntityReference("lt")
のようにして&lt;エンティティを作成できます。

#2>node.attributes.item(0).nodeValue = "test>"
node.attributes.item(0).nodeValue = "test<"
の間違いですね

>MSXMLの仕様なのかなと
MSXMLのリファレンスで

According to the W3C DOM specification, an XML parser can completely expand entity references into entities before the structure model is passed to the DOM. When these entity references are expanded, the document tree does not contain any entity references.

When Microsoft&reg; XML Core Services (MSXML) vali...続きを読む

Q文字列として"(ダブルコーテーション)を表示させる方法

こんにちは。文字列として、ダブルコーテーションを表示させるには、どうすればよいのか教えてください。m(__)m


例えば、
<font size="2">あいうえお</font>

というタグの「あいうえお」の部分が、セルA1にあった場合、

="<font size="2">"&A1&"</font>"という表示にしたいのです。

"2"のダブルコーテーションも文字列として表示させるには、どうすればよろしいのでしょうか。

教えてください。よろしくお願い致します。

Aベストアンサー

こんにちは~

表示形式は 「標準」 のままで、
ダブルコーテーションを、ダブルコーテーションで囲んでください。

""2""

="<font size=""2"">"&A1&"</font>"

としてみてください。

Qタグの有無の判定

みなさん、初めまして。

今、XSLTでXMLファイルをJavaファイルに変換するxslファイルを
書いているのですが質問のタイトルの通りタグの有無を判定して処理
を行いたいのですが、どのようにすれば可能でしょうか?

例えば、XMLファイル中に

<work>
<value></value>
</work>
<work>
<value>test</value>
<work>

上記のような内容があった場合にのタグの値の有無で処理を行うには

<xsl:choose>
<xsl:when test="value=''">hogehoge</xsl:when>
<xsl:otherwise>fugafuga</xsl:otherwise>
</xsl:choose>

とすれば可能だと思うのですが(もっと簡単な方法もあるかも
しれませんが・・・)、workタグの中にvalueタグが無かった
場合にAという処理をし、タグがある場合にはBと言う処理を
行うという事をしたいのです。

それではよろしくお願い致します。

みなさん、初めまして。

今、XSLTでXMLファイルをJavaファイルに変換するxslファイルを
書いているのですが質問のタイトルの通りタグの有無を判定して処理
を行いたいのですが、どのようにすれば可能でしょうか?

例えば、XMLファイル中に

<work>
<value></value>
</work>
<work>
<value>test</value>
<work>

上記のような内容があった場合にのタグの値の有無で処理を行うには

<xsl:choose>
<xsl:when test="value=''">hogehoge</xsl:when>
<xsl:otherwise>fugafuga</xsl:otherwi...続きを読む

Aベストアンサー

タグの値の有無(空か否か)を判断したいのであれば
<xsl:when test="value=''">hogehoge</xsl:when>
でいいでしょう

タグの有無を判断するなら
<xsl:when test="count(value)=0">hogehoge</xsl:when>
ですね



<value></value>のような空要素と、タグが無いというのは同義語ではないです。どちらを指していたのでしょうか?

QXSLTにてタグ名を取得する方法

XML勉強中です。実は、XML文書に決められたタグがあって、その中身を探してXSL変換、というのは覚えたのですが、ふと迷ってしまいました。
たとえば、トップレベルにあるタグの名前が不明な場合、エレメントの一覧を取得するにはどうしたら良いのでしょうか?
自分でXMLを記述しておいてそれはないだろと言われそうなのですが、HTMLのための資源としてではなく、データとしての利用を考えたときにふと悩んでしまいました。

<person>
 <name> <ID> etc...
</person>
<company>
 <name> <adress> <tel>etc...
</company>

このとき、personとcompanyを取得したいのですが・・・。
template match="/" にて value-of select="name(.)" とか一通り試したのですが、出てくれませんでした。
まだはっきりとXSLTの書き方を習得していないので、とてつもなくアホな質問かもしれませんが、よろしくお願いいたします。

Aベストアンサー

正しいやり方かどうかわかりませんが、参考まで...
<xsl:template match="/">
<!-- root -->
<xsl:for-each select="./*">
<xsl:value-of select="name()"/><br/>
</xsl:for-each>
<!-- top -->
<xsl:for-each select="./*/*">
<xsl:text> </xsl:text><xsl:value-of select="name()"/><br/>
</xsl:for-each>
<!-- second -->
<xsl:for-each select="./*/*/*">
<xsl:text>  </xsl:text><xsl:value-of select="name()"/><br/>
</xsl:for-each>
</xsl:template>

QXSL中の改行、タブを無効にしたい。

XMLドキュメントにXSLを適用すると
XSL中の改行やタブがそのまま反映されてしまいます。

改行を無くすと1行が長くなってしまい編集が大変で困っています。

どうしたらよいのでしょうか?

XSL:
<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet xml:space="default" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema">
<xsl:output method="text" />
<xsl:template match="/">
<xsl:for-each select="//z:row">
<xsl:choose>
<xsl:when test="(@MACHINE='DELL')">
</xsl:when>
<xsl:when test="(@MACHINE='APPLE')">
</xsl:when>
<xsl:when test="(@MACHINE='HP')">
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@MACHINE" />,
<xsl:value-of select="substring(@PARTS_NO,1,1)" />-<xsl:value-of select="substring(@PARTS_NO,2,3)" />-<xsl:value-of select="substring(@PARTS_NO,5,3)" />-<xsl:value-of select="substring(@PARTS_NO,8,2)" />,<xsl:value-of select="@STATUS" />,<xsl:value-of select="@STOCK_NUM" /><xsl:text>&#xA;</xsl:text>
<xsl:if test="not(@MACHINE=following-sibling::z:row/@MACHINE)">
<xsl:text>,&#xA;</xsl:text>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

XMLドキュメントにXSLを適用すると
XSL中の改行やタブがそのまま反映されてしまいます。

改行を無くすと1行が長くなってしまい編集が大変で困っています。

どうしたらよいのでしょうか?

XSL:
<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet xml:space="default" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema">
<xsl:output method="text" />
<xsl:template match="/">
<xsl:for-each sel...続きを読む

Aベストアンサー

状況が再現し、一応除去もできるようにはなりましたけどなんか釈然としません。
やってみた方法は、XSLを2段階適用するというやり方で
transformNodeToObjectを使って別のXML(output method="xml")に変換し
(XSLで一行分のレコードをxsl:elementで1つのエレメントにする)
transformNodeで
<xsl:value-of select="translate(., '

', '')" />
みたいにして作成したエレメントから空白文字を取り除く+<xsl:text>
</xsl:text>
(output methid="text")
するというようなやり方です。
でも、いちいちこんなやり方するなら、別に一行に書けばいいんじゃないかとか思えて釈然としません。
ところで、
std::string s = pXMLDOMDoc->transformNode(pXSLDOMDoc);
replace(s, std::string("\r\n"), std::string("\n"));
ってうまくいきますか?
こういう置換がプログラムでできるなら、
transformNodeで出力したものからタブと取り除くのも難しくないと思うのですが、
スタイルシートで、:CR:観たいなものをレコード区切りとして付与して
スペース、タブ、改行を取り除いた後
:CR:を改行に置換するというような手順でいいような気がします。
どっちかというと、そういうプログラムで(整形)処理するのが、簡単でいいような気がするのですが。

状況が再現し、一応除去もできるようにはなりましたけどなんか釈然としません。
やってみた方法は、XSLを2段階適用するというやり方で
transformNodeToObjectを使って別のXML(output method="xml")に変換し
(XSLで一行分のレコードをxsl:elementで1つのエレメントにする)
transformNodeで
<xsl:value-of select="translate(., '

', '')" />
みたいにして作成したエレメントから空白文字を取り除く+<xsl:text>
</xsl:text>
(output methid="text")
するというようなやり方です。
で...続きを読む

Qシート参照で変数を使いたい(EXCEL)

通常、Excelで別シートのセルを参照する時は「'シート名'!B3」といった数式になりますが、この「シート名」をユーザーに入力してもらうような仕組みを作りたいと考えています。

・あるシートのA3(例)にシート名を入力すると、B4セルに入力されたシートのB3セルの内容が表示される

このようなこと、可能でしょうか?

Aベストアンサー

INDIRECT関数を使うといいでしょう。

セルA1に入力されたシート名の、セルB3を参照する場合

   =INDIRECT(A1& "!B3")


また上記ではセルB3が固定になってますが、
セルA1 に参照したい【シート名】をいれ
セルA2 に参照したい【セル番地】まで入れておくと
なお、使い勝手がよくなるかも知れませんね。

   =INDIRECT(A1& "!" & A2)
 
 
 

Qtxtファイル内の指定の単語の数を数えたいのですが何か方法はありますか

txtファイル内の指定の単語の数を数えたいのですが何か方法はありますか?
たとえば「花」と入力してその単語の個数を調べたいのです

Aベストアンサー

テキストファイルのGrep機能(一括検索・置換)機能のあるフリーウェアでテキストファイルを検索すれば、たいていは置換する前に「何個見つかりました」とメッセージが表示されるので分かると思いますよ。
ちなみにわたしはDevasという置換ソフトを使ってます。
検索だけして検索数を確認したら置換せずにキャンセルしちゃえばよいので、これで用は充分足りると思います。

参考URL:http://www.vector.co.jp/soft/win95/util/se162621.html


おすすめ情報