首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用对XML文件进行排序

如何使用对XML文件进行排序
EN

Stack Overflow用户
提问于 2020-08-20 19:52:36
回答 1查看 192关注 0票数 0

我想对这个XML进行排序,以便首先显示相同类型的人口学数据,就像所有的staty_type=“到达”显示在顶部,然后显示所有的单击等等。

下面是一个示例对象:

代码语言:javascript
复制
<?xml version="1.0"?>
<properties date="2020-06-23">
    <property>
        <order start="2020-06-23" end="2020-06-23">52658</order>
        <demographics demographic="Age" stat_type="REACH">
            <value category="18-24">36</value>
            <value category="25-34">149</value>
        </demographics>
        <demographics demographic="Age" stat_type="CLICK">
            <value category="18-24">6</value>
            <value category="25-34">37</value>
        </demographics>
        <demographics demographic="Gender" stat_type="REACH">
            <value category="female">402</value>
            <value category="male">188</value>
        </demographics>
        <demographics demographic="Gender" stat_type="CLICK">
            <value category="female">107</value>
            <value category="male">44</value>
        </demographics>

    </property>
</properties> 

我能够迭代XML。但是,无法执行排序。

代码语言:javascript
复制
    @doc = Nokogiri::XML(File.open("public/test.xml"))
        builder = @doc.xpath("//property")

        builder.search('./demographics').sort_by{|t| puts t['stat_type']}.each do |table|                           
                puts table.to_s
        end

我需要这个表单中的最后一个XML。

代码语言:javascript
复制
<?xml version="1.0"?>
<properties date="2020-06-23">
    <property>
        <order start="2020-06-23" end="2020-06-23">PBNI152658</order>
        <demographics demographic="Age" stat_type="REACH">
            <value category="18-24">36</value>
            <value category="25-34">149</value>
        </demographics>
        <demographics demographic="Gender" stat_type="REACH">
            <value category="female">402</value>
            <value category="male">188</value>
        </demographics>
        <demographics demographic="Age" stat_type="CLICK">
            <value category="18-24">6</value>
            <value category="25-34">37</value>
        </demographics>
        <demographics demographic="Gender" stat_type="CLICK">
            <value category="female">107</value>
            <value category="male">44</value>
        </demographics>

    </property>
</properties>
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-21 04:50:54

当您做像builder.search('./demographics')这样的事情时,您只需创建一个新的节点集,其中包含一些从初始XML中过滤出来的节点。即使对这个新节点进行排序,也不会影响初始文档本身。

要对初始文档的节点进行排序,您必须重新构建所讨论节点的子节点(在您的示例中为<property>)。这里还有一个小小的额外挑战-- Nokogiri解析的更多节点需要考虑,而不仅仅是需要排序的节点:

代码语言:javascript
复制
pry(main)> @doc.at_xpath("//property").children.map(&:node_name)
=> ["text", "order", "text", "demographics", "text", "demographics", "text", "demographics", "text", "demographics", "text"]

因此,我们必须做的是只对人口统计节点进行排序,并保持其他所有内容不受影响。这样做的方法之一是:

代码语言:javascript
复制
property_node = @doc.at_xpath("//property")

nodes_to_sort = property_node.children.dup

# My sorting logic is dumb here, apply your own as necessary
sorted_demographics = nodes_to_sort.select { |n| n.node_name == "demographics" }.sort_by { |n| n.attr("stat_type") }.reverse

# Create an empty nodeset. There should be a more idiomatic and readable way but this trick works too
new_nodeset = nodes_to_sort - nodes_to_sort

nodes_to_sort.each do |n|
  case n.node_name
  when "demographics"
    new_nodeset << sorted_demographics.shift
  else
    new_nodeset << n
  end
end

property_node.children = new_nodeset

瞧!-我们现在被分类了:

代码语言:javascript
复制
pry(main)> puts @doc
<?xml version="1.0"?>
<properties date="2020-06-23">
    <property>
        <order start="2020-06-23" end="2020-06-23">52658</order>
        <demographics demographic="Gender" stat_type="REACH">
            <value category="female">402</value>
            <value category="male">188</value>
        </demographics>
        <demographics demographic="Age" stat_type="REACH">
            <value category="18-24">36</value>
            <value category="25-34">149</value>
        </demographics>
        <demographics demographic="Gender" stat_type="CLICK">
            <value category="female">107</value>
            <value category="male">44</value>
        </demographics>
        <demographics demographic="Age" stat_type="CLICK">
            <value category="18-24">6</value>
            <value category="25-34">37</value>
        </demographics>

    </property>
</properties>

注意:从上面的解决方案中可以看出一点--我不太了解nokogiri的XML构建功能,因此有可能有一些方法可以用更少的代码/更惯用的方式实现相同的结果。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63512283

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档