Java - 如果属性包含在以逗号分隔的字符串中,则删除所有元素

Java - Remove all elements if attribute is included in a comma-seperated string

我正在修改遗留代码,如果字符串中包含其 id 属性,我需要删除所有元素。

要删除的示例 ID:

String idToExclude = "2,4,6,8,10";

假设 Element doc 包含以下内容:

<StoreOffers>
    <Store StoreID="0">
        <Offers>
            <Offer OfferID="1"/>
            <Offer OfferID="2"/>
            <Offer OfferID="3"/>
            <Offer OfferID="4"/>
            <Offer OfferID="5"/>
            <Offer OfferID="6"/>
            <Offer OfferID="7"/>
            <Offer OfferID="8"/>
            <Offer OfferID="9"/>
            <Offer OfferID="10"/>
        </Offers>
    </Store>
</StoreOffers>

编辑 这是我试过的,这是实际的代码。我也更新了 xml:

String offersToExclude = getOffersToExclude(customer);

                    StringReader asa = new StringReader(storeOffers);
                    SAXBuilder builder = new SAXBuilder();
                    Document doc = builder.build(asa);
                    Element root = doc.getRootElement();
                    List<Element> stores = root.getChildren();

                    for (Element store : stores) {
                        storeid = store.getAttributeValue("StoreID");
                        List<Element> offers = store.getChild("Offers").getChildren();

                        for(Element offer : offers) {
                            String offerid = offer.getAttributeValue("OfferID");

                            if(CCSUtils.isNotEmpty(offerid)) {
                                if(offersToExclude.contains(offerid)) {
                                    store.getChild("Offers").removeChild(offer); //This doesn't work
                                }
                            }
                        }
                    }

由于不知道jdom的版本,以下解决方案基于2.0.6版本(最新29/10/2018)

首先,方法removeChild不适用于String参数,只有两种方法:public boolean removeChild(final String cname)public boolean removeChild(final String cname, final Namespace ns)

要实现您的预​​期,只需操作从父 ElementElement.getChildren() 方法获取的元素。如 Element.getChildren()

Java Doc 中所述

This returns a List of all the child elements nested directly (one level deep) within this element, as Element objects. If this target element has no nested elements, an empty List is returned. The returned list is "live"in document order and changes to it affect the element's actual contents.

Sequential traversal through the List is best done with a Iterator since the underlying implement of List.size() may not be the most efficient.

因此我们可以使用迭代器来迭代子元素,如果 OfferID 是我们的目标之一,则删除该元素。以下代码演示了如何完成此操作。

import java.io.IOException;
import java.io.StringReader;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;

public class DeleteChild {
    public static void main(String[] args) throws IOException, JDOMException {
        // Should not use String.contains method as OfferId="1" will be deleted.
        String[] offersToExclude = "2,4,6,8,10".split(",");

        StringReader stringReader = new StringReader(getXml());
        SAXBuilder builder = new SAXBuilder();
        Document doc = builder.build(stringReader);
        Element root = doc.getRootElement();
        System.out.println("*****Before Remove*****");
        System.out.println(new XMLOutputter(Format.getPrettyFormat(), null).outputString(root));
        List<Element> stores = root.getChildren();

        for (Element store : stores) {
            List<Element> offers = store.getChild("Offers").getChildren();
            Iterator<Element> offerIterator = offers.iterator();
            while (offerIterator.hasNext()) {
                Element offer = offerIterator.next();
                if (Arrays.asList(offersToExclude).contains(offer.getAttributeValue("OfferID"))) {
                    offerIterator.remove();
                }
            }
        }
        System.out.println("*****After Remove*****");
        System.out.println(new XMLOutputter(Format.getPrettyFormat(), null).outputString(root));
    }

    private static String getXml() {
        return "   <StoreOffers>                                          "
                + "    <Store StoreID=\"0\">                              "
                + "        <Offers>                                       "
                + "        <Offer OfferID=\"1\"/>                         "
                + "        <Offer OfferID=\"2\"/>                         "
                + "        <Offer OfferID=\"3\"/>                         "
                + "        <Offer OfferID=\"4\"/>                         "
                + "        <Offer OfferID=\"5\"/>                         "
                + "        <Offer OfferID=\"6\"/>                         "
                + "        <Offer OfferID=\"7\"/>                         "
                + "        <Offer OfferID=\"8\"/>                         "
                + "        <Offer OfferID=\"9\"/>                         "
                + "        <Offer OfferID=\"10\"/>                        "
                + "        </Offers>                                      "
                + "    </Store>                                           "
                + "</StoreOffers>                                         ";
    }
}