1

orderEvents 要素があり、その要素に orderEvent または空のテキストではない子ノードがある場合、エラーを追加する次のコードがあります。テストケースは、私が求めているものをよりよく示しています。

orderEventsXPATH 式は、要素内に空のスペースがある場合を除き、すべての場合に機能します。以下のテスト ケースvalidVendorPaymentFormat7を参照してください。これが私のXPATH式です。

"./expectedVendorPaymentTransactions/orderEvents/node()[not(self::orderEvent) or self::text()[normalize-space(.)!='']]"

テストケース:

<TestData>
  <TestcaseList>
    <Testcase>
      <rootIdentifier>validVendorPaymentFormat1</rootIdentifier>
      <expectedVendorPaymentTransactions>
        <orderEvents></orderEvents>
      </expectedVendorPaymentTransactions>
    </Testcase>
    <Testcase>
      <rootIdentifier>validVendorPaymentFormat2</rootIdentifier>
    </Testcase>
    <Testcase>
      <rootIdentifier>validVendorPaymentFormat3</rootIdentifier>
      <expectedVendorPaymentTransactions>
      </expectedVendorPaymentTransactions>
    </Testcase>
    <Testcase>
      <rootIdentifier>validVendorPaymentFormat4</rootIdentifier>
      <expectedVendorPaymentTransactions>
        <orderEvents><orderEvent>SOME_EVENT</orderEvent></orderEvents>
      </expectedVendorPaymentTransactions>
    </Testcase>
     <Testcase>
      <rootIdentifier>validVendorPaymentFormat5</rootIdentifier>
      <expectedVendorPaymentTransactions>
        <orderEvents><orderEvent>SOME_EVENT</orderEvent></orderEvents>
      </expectedVendorPaymentTransactions>
    </Testcase>
    <Testcase>
      <rootIdentifier>validVendorPaymentFormat6</rootIdentifier>
      <expectedVendorPaymentTransactions>
        <orderEvents><orderEvent>SOME_EVENT</orderEvent><orderEvent>SOME_EVENT</orderEvent></orderEvents>
      </expectedVendorPaymentTransactions>
    </Testcase>
    <Testcase>
      <rootIdentifier>validVendorPaymentFormat7</rootIdentifier>
      <expectedVendorPaymentTransactions>
        <orderEvents>
          <orderEvent>SOME_EVENT</orderEvent>
        </orderEvents>
      </expectedVendorPaymentTransactions>
    </Testcase>
  </TestcaseList>
</TestData>

失敗するケースはvalidVendorPaymentFormat7 です

失敗メッセージ:

[exec] Failure:
 [exec]   Order vendor payments format contains elements other than orderEvent for validVendorPaymentFormat7 ["\n          ", "\n        "].
 [exec]   <false> is not true.

失敗したケースを次のように変更します。

        <Testcase>
          <rootIdentifier>validVendorPaymentFormat7</rootIdentifier>
          <expectedVendorPaymentTransactions>
            <orderEvents><orderEvent>SOME_EVENT</orderEvent></orderEvents>
          </expectedVendorPaymentTransactions>
        </Testcase>

結果は合格。

残念ながら、http://www.freeformatter.com/xpath-tester.htmlテスト ケース 7 では、期待どおりに空のリストが返されます。

更新 - コードの追加
Ruby バージョン: 1.9
irb -v = 0.9.6

テスト ファイル:

require 'rexml/document'

xpath = "//expectedVendorPaymentTransactions/orderEvents/node()[not(self::orderEvent) or self::text()[translate(., ' &#10;', '')!='']]"
document = REXML::Document.new <<EOF 
    <Testcase>
      <rootIdentifier>validVendorPaymentFormat7</rootIdentifier>
      <expectedVendorPaymentTransactions>
        <orderEvents>
          <orderEvent>SOME_EVENT</orderEvent>
        </orderEvents>
      </expectedVendorPaymentTransactions>
    </Testcase>
EOF

document2 = REXML::Document.new <<EOF 
    <Testcase>
      <rootIdentifier>validVendorPaymentFormat7</rootIdentifier>
      <expectedVendorPaymentTransactions>
        <orderEvents><orderEvent>SOME_EVENT</orderEvent></orderEvents>
      </expectedVendorPaymentTransactions>
    </Testcase>
EOF

puts "1: #{REXML::XPath.match(document, xpath).inspect}"
puts "2: #{REXML::XPath.match(document2, xpath).inspect}"

出力:

irb(main):001:0> load './test/test_rexp.rb'
1: ["\n          ", "\n        "]
2: []
=> true

Jens の最新リビジョン:

irb(main):009:0> load './test/test_rexp.rb'
1: ", "
2: ", "
=> true
4

2 に答える 2

1

Ruby は改行を空白として処理しないようnormalize-space(...)です。空白以外が含まれているかどうかに関心があるので、すべての空白を削除してください。translate(...)手に入れることができます。最初のパラメーターは一致するもの、2 番目の文字列は一致するもの、3 番目のパラメーターは置換する文字を示します。空であるため、一致したすべての文字が削除されます。

translate(., ' &#10;', '')

Perl の XPath で問題を再現でき、次のクエリで解決されました。

/expectedVendorPaymentTransactions/orderEvents/node()[not(self::orderEvent) or self::text()[translate(., ' &#10;', '')!='']]

更新: Ruby は XML エンティティを正しく解決していないようですが、\n代わりに for newline を使用できます:

translate(., ' \n', '')
于 2013-09-24T07:28:14.617 に答える
1

Dropping the whitespace handling from XPATH and using a rather easy ruby workaround works.

Working code:

require 'rexml/document'
require 'rexml/text'

xpath = "//expectedVendorPaymentTransactions/orderEvents/node()[not(self::orderEvent)]"
document = REXML::Document.new <<EOF 
    <Testcase>
      <rootIdentifier>validVendorPaymentFormat7</rootIdentifier>
      <expectedVendorPaymentTransactions>
        <orderEvents>
          <orderEvent>Fulfill</orderEvent>
        </orderEvents>
      </expectedVendorPaymentTransactions>
    </Testcase>
EOF

document2 = REXML::Document.new <<EOF 
    <Testcase>
      <rootIdentifier>validVendorPaymentFormat7</rootIdentifier>
      <expectedVendorPaymentTransactions>
        <orderEvents><orderEvent>Fulfill</orderEvent></orderEvents>
      </expectedVendorPaymentTransactions>
    </Testcase>
EOF

elements = REXML::XPath.match(document, xpath)
elements.reject! { |element| 
      element.instance_of?(REXML::Text) and element.value.gsub(/[\n ]/,"") == ''
    }
puts "1: #{elements.inspect}"

elements2 = REXML::XPath.match(document2, xpath)
elements2.reject! { |element| 
      element.instance_of?(REXML::Text) and element.value.gsub(/[\n\t ]/,"") == ''
    }
puts "2: #{elements2.inspect}"
于 2013-09-26T21:08:55.350 に答える