1

以下の XML があります。空のテキストを持つ子要素はほとんどありません。

doc = <<'XML'
<Book>
    <BookId>BK45647</BookId>
    <BookName>The Client by John Grisham</BookName>
    <BookAuthenticationCode></BookAuthenticationCode>
    <BookCategory>Suspense</BookCategory>
    <BookSequence></BookSequence>
    <BookPublisherInfo>
        <PublisherId>PBBK12345</PublisherId>
        <PublisherName>Mc.GrawHill</PublisherName>
        <PublisherIndex></PublisherIndex>
        <PublisherCategoryQuota></PublisherCategoryQuota>
    </BookPublisherInfo>
    <BookPurchaselist>
       <Customer>
           <FirstName>John</FirstName>
           <LastName>Smith</LastName>
           <MiddleName></MiddleName>
           <NickName></NickName>
       </Customer>
        <Customer>
           <FirstName>Winston</FirstName>
           <LastName>Churchill</LastName>
           <MiddleName></MiddleName>
           <NickName></NickName>
       </Customer>
    </BookPurchaselist>
</Book>
XML

以下のコードで試してみましたが、どういうわけか正しく動作しません。

cust = doc.at_xpath("//Customer")
cust.each do |cust_obj|
    if cust_obj.has_text? == false
       cust_obj.delete
    end
end

これはどういうわけか正しく機能しておらず、以下の出力が得られます

<Book>
    <BookId>BK45647</BookId>
    <BookName>The Client by John Grisham</BookName>
    <BookAuthenticationCode></BookAuthenticationCode>
    <BookCategory>Suspense</BookCategory>
    <BookSequence></BookSequence>
    <BookPublisherInfo>
        <PublisherId>PBBK12345</PublisherId>
        <PublisherName>Mc.GrawHill</PublisherName>
        <PublisherIndex></PublisherIndex>
        <PublisherCategoryQuota></PublisherCategoryQuota>
    </BookPublisherInfo>
    <BookPurchaselist>
       <Customer>
           <FirstName>John</FirstName>
           <LastName>Smith</LastName>
           <MiddleName></MiddleName>
       </Customer>
        <Customer>
           <FirstName>Winston</FirstName>
           <LastName>Churchill</LastName>
           <NickName></NickName>
       </Customer>
    </BookPurchaselist>
</Book>

空のテキストを持つ要素はほとんど取得されておらず、そのまま残っている要素はほとんどありません。特定の xpath (空のデータ) で要素を再帰的に削除し、XML を書き直すにはどうすればよいですか。

ここで立ち往生..提案が必要です。

4

1 に答える 1

4
doc.xpath('//Customer/child::*[not(text())]').each do |node|
  node.remove
end

not(node())子を持たないノードも削除したい場合に使用できます。

EDIT:完全な作業例(上記と同じコードを使用)

require 'nokogiri'

xml = <<-XML
<Book>
    <BookId>BK45647</BookId>
    <BookName>The Client by John Grisham</BookName>
    <BookAuthenticationCode></BookAuthenticationCode>
    <BookCategory>Suspense</BookCategory>
    <BookSequence></BookSequence>
    <BookPublisherInfo>
        <PublisherId>PBBK12345</PublisherId>
        <PublisherName>Mc.GrawHill</PublisherName>
        <PublisherIndex></PublisherIndex>
        <PublisherCategoryQuota></PublisherCategoryQuota>
    </BookPublisherInfo>
    <BookPurchaselist>
       <Customer>
           <FirstName>John</FirstName>
           <LastName>Smith</LastName>
           <MiddleName></MiddleName>
       </Customer>
        <Customer>
           <FirstName>Winston</FirstName>
           <LastName>Churchill</LastName>
           <NickName></NickName>
       </Customer>
    </BookPurchaselist>
</Book>
XML

doc = Nokogiri.parse(xml)

doc.xpath('//Customer/child::*[not(text())]').each do |node|
  node.remove
end

puts doc.to_s

このプログラムの出力は次のとおりです。

<?xml version="1.0"?>
<Book>
    <BookId>BK45647</BookId>
    <BookName>The Client by John Grisham</BookName>
    <BookAuthenticationCode/>
    <BookCategory>Suspense</BookCategory>
    <BookSequence/>
    <BookPublisherInfo>
        <PublisherId>PBBK12345</PublisherId>
        <PublisherName>Mc.GrawHill</PublisherName>
        <PublisherIndex/>
        <PublisherCategoryQuota/>
    </BookPublisherInfo>
    <BookPurchaselist>
       <Customer>
           <FirstName>John</FirstName>
           <LastName>Smith</LastName>

       </Customer>
        <Customer>
           <FirstName>Winston</FirstName>
           <LastName>Churchill</LastName>

       </Customer>
    </BookPurchaselist>
</Book>
于 2012-07-06T18:41:19.017 に答える