如何过滤掉XML的特定节点?

时间:2010-01-18 17:18:43

标签: xml flex actionscript-3 actionscript e4x

采用这个XML示例:

<root>
  <grandParent GPid="1" hidden="false">
    <parent Pid="1" hidden="false">
      <child Cid="1" hidden="false"/>
      <child Cid="2" hidden="true"/>
    </parent>
    <parent Pid="2" hidden="false">
      <child Cid="3" hidden="false"/>
      <child Cid="4" hidden="false"/>
    </parent>
  </grandParent>
  <grandParent GPid="2" hidden="false">
    <parent Pid="3" hidden="false">
      <child Cid="5" hidden="true"/>
    </parent>
    <parent Pid="4" hidden="true">
      <child Cid="6" hidden="false"/>
    </parent>
  </grandParent>
  <grandParent GPid="3" hidden="true">
    <parent Pid="5" hidden="false">
      <child Cid="7" hidden="false"/>
    </parent>
  </grandParent>
</root>

我需要某种过滤器来获取此类的副本,其中所有标记为“隐藏”的节点都被删除,如下所示:

<root>
  <grandParent GPid="1" hidden="false">
    <parent Pid="1" hidden="false">
      <child Cid="1" hidden="false"/>
    </parent>
    <parent Pid="2" hidden="false">
      <child Cid="3" hidden="false"/>
      <child Cid="4" hidden="false"/>
    </parent>
  </grandParent>
  <grandParent GPid="2" hidden="false">
    <parent Pid="3" hidden="false"/>
  </grandParent>
</root>

我尝试过使用类似的东西

var newXML:XML = XML(root.(grandParent.@hidden != "true").(grandParent.parent.@hidden != "true").(grandParent.parent.child.@hidden !=true);

但这真的只是让我回到原来的XML(因为我要求根据那些条件得到满足我得到根)。我理解为什么我的方法不起作用,但我不知道从哪里开始。

2 个答案:

答案 0 :(得分:1)

假设您的XML在变量myXML中,您可以使用这样的递归函数。这样做,你不会被绑定到你的元素的名称(即。grandParent,parent,child),你不会受到级别数量的限制(即你可以添加一个<pet>节点每个<child>节点。)

public function removeElements( avXml:XML, avAttributeName:String, avCondition:String) {

    var lvAttributeValue:String;
    var lvXml:XML;

    var lvXmlList:XMLList = new XMLList();
    for each( lvXml in avXml.children() ) {
        lvAttributeValue = lvXml.attribute( avAttributeName );
        if( lvAttributeValue == avCondition )
            lvXmlList += lvXml;

        avXml.setChildren( lvXmlList ); 
    }

    for each( var lvXmlChild:XML in avXml.children() ) {
        removeElements(lvXmlChild,avAttributeName,avCondition);
    } 
}


removeElements(myXML, "hidden", "false");
trace(myXML.toXMLString());

 <root hidden="false">
      <grandParent GPid="1" hidden="false">
        <parent Pid="1" hidden="false">
          <child Cid="1" hidden="false"/>
        </parent>
        <parent Pid="2" hidden="false">
          <child Cid="3" hidden="false"/>
          <child Cid="4" hidden="false"/>
        </parent>
      </grandParent>
      <grandParent GPid="2" hidden="false">
        <parent Pid="3" hidden="false"/>
      </grandParent>
    </root>

答案 1 :(得分:0)

所以这就是我能想到的,但我不喜欢循环。如果你有更好的方法,请告诉我:

var newXML:XML = new XML(root);
var i:uint=0;
for(i=0;i<newXML.grandparent.parent.child.(@hidden == false).length();i++){
  delete newXML.grandparent.parent.child.(@hidden == false)[0];
  //always [0] since the list is shortened by 1 each iteration
}
for(i=0;i<newXML.grandparent.parent.(@hidden == false).length();i++){
  delete newXML.grandparent.parent.(@hidden == false)[0];
}
for(i=0;i<newXML.grandparent.(@hidden == false).length();i++){
  delete newXML.grandparent.(@hidden == false)[0];
}