如果子节点等于数组值,则删除XML节点

时间:2019-01-26 07:54:08

标签: php xml

如果“ ProductID”是数组中的值之一,我正在尝试从XML中删除“ Product”节点。由于某些原因,我的代码仅删除在数组中找到的具有第一个“ ProductID”的“ Product”节点。如果所有“ Product”节点的“ ProductID”是数组中的值之一,该如何删除?有更好的方法来编码吗?

XML示例:

2019-01-26 12:43:11.619  INFO 17684 --- [           main] c.w.service.service.ServiceApplication   : Starting ServiceApplication on DESKTOP-T03T8BR with PID 17684 (D:\hello\service\target\classes started by Nexus in D:\hello\service)
2019-01-26 12:43:11.624  INFO 17684 --- [           main] c.w.service.service.ServiceApplication   : No active profile set, falling back to default profiles: default
2019-01-26 12:43:11.775  INFO 17684 --- [           main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@2d2e5f00: startup date [Sat Jan 26 12:43:11 PKT 2019]; root of context hierarchy
2019-01-26 12:43:13.912  INFO 17684 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.ws.config.annotation.DelegatingWsConfiguration' of type [org.springframework.ws.config.annotation.DelegatingWsConfiguration$$EnhancerBySpringCGLIB$$2e4eba9b] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2019-01-26 12:43:13.942  WARN 17684 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'annotationActionEndpointMapping' defined in class path resource [org/springframework/ws/config/annotation/DelegatingWsConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.ws.soap.addressing.server.AnnotationActionEndpointMapping]: Factory method 'annotationActionEndpointMapping' threw exception; nested exception is java.lang.NoClassDefFoundError: org/springframework/xml/DocumentBuilderFactoryUtils
2019-01-26 12:43:13.958  INFO 17684 --- [           main] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2019-01-26 12:43:13.977 ERROR 17684 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'annotationActionEndpointMapping' defined in class path resource [org/springframework/ws/config/annotation/DelegatingWsConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.ws.soap.addressing.server.AnnotationActionEndpointMapping]: Factory method 'annotationActionEndpointMapping' threw exception; nested exception is java.lang.NoClassDefFoundError: org/springframework/xml/DocumentBuilderFactoryUtils
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:587) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1250) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1099) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:205) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:226) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:709) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:534) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:388) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1246) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1234) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
    at com.web.service.service.ServiceApplication.main(ServiceApplication.java:10) [classes/:na]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.ws.soap.addressing.server.AnnotationActionEndpointMapping]: Factory method 'annotationActionEndpointMapping' threw exception; nested exception is java.lang.NoClassDefFoundError: org/springframework/xml/DocumentBuilderFactoryUtils
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:579) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    ... 18 common frames omitted
Caused by: java.lang.NoClassDefFoundError: org/springframework/xml/DocumentBuilderFactoryUtils
    at org.springframework.ws.soap.addressing.version.AbstractAddressingVersion.<clinit>(AbstractAddressingVersion.java:66) ~[spring-ws-core-3.0.6.RELEASE.jar:na]
    at org.springframework.ws.soap.addressing.server.AbstractAddressingEndpointMapping.initDefaultStrategies(AbstractAddressingEndpointMapping.java:107) ~[spring-ws-core-3.0.6.RELEASE.jar:na]
    at org.springframework.ws.soap.addressing.server.AbstractAddressingEndpointMapping.<init>(AbstractAddressingEndpointMapping.java:98) ~[spring-ws-core-3.0.6.RELEASE.jar:na]
    at org.springframework.ws.soap.addressing.server.AbstractActionEndpointMapping.<init>(AbstractActionEndpointMapping.java:38) ~[spring-ws-core-3.0.6.RELEASE.jar:na]
    at org.springframework.ws.soap.addressing.server.AbstractActionMethodEndpointMapping.<init>(AbstractActionMethodEndpointMapping.java:34) ~[spring-ws-core-3.0.6.RELEASE.jar:na]
    at org.springframework.ws.soap.addressing.server.AnnotationActionEndpointMapping.<init>(AnnotationActionEndpointMapping.java:60) ~[spring-ws-core-3.0.6.RELEASE.jar:na]
    at org.springframework.ws.config.annotation.WsConfigurationSupport.annotationActionEndpointMapping(WsConfigurationSupport.java:120) ~[spring-ws-core-3.0.6.RELEASE.jar:na]
    at org.springframework.ws.config.annotation.DelegatingWsConfiguration$$EnhancerBySpringCGLIB$$2e4eba9b.CGLIB$annotationActionEndpointMapping$4(<generated>) ~[spring-ws-core-3.0.6.RELEASE.jar:na]
    at org.springframework.ws.config.annotation.DelegatingWsConfiguration$$EnhancerBySpringCGLIB$$2e4eba9b$$FastClassBySpringCGLIB$$d551914b.invoke(<generated>) ~[spring-ws-core-3.0.6.RELEASE.jar:na]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:361) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    at org.springframework.ws.config.annotation.DelegatingWsConfiguration$$EnhancerBySpringCGLIB$$2e4eba9b.annotationActionEndpointMapping(<generated>) ~[spring-ws-core-3.0.6.RELEASE.jar:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_191]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_191]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_191]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_191]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE]
    ... 19 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.springframework.xml.DocumentBuilderFactoryUtils
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382) ~[na:1.8.0_191]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_191]
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349) ~[na:1.8.0_191]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_191]
    ... 36 common frames omitted

我做了什么:

SELECT * FROM videos ORDER BY id ASC LIMIT 0, 10 #Fetch first 10
SELECT * FROM videos ORDER BY id ASC LIMIT 10, 10 #Fetch next 10

结果,该代码仅删除了具有“ ProductID”等于“ ZZ-DS”的“ Product”节点。

1 个答案:

答案 0 :(得分:0)

问题是试图遍历数组的内容然后删除该数组的某些部分的情况,该数组与循环不同步。如果将echo $product->ProductID.PHP_EOL;添加到循环中并查看显示的内容,则可以看到此信息。

有两种方法可以解决此问题。第一个只是使用XPath查找要使用的节点列表,然后在这些节点上循环并检查ID并根据需要删除。当您遍历节点的XPath列表时,在删除节点之后,它不会改变...

$products = $xml->xpath("//Product");
foreach($products as $product) {
    if (in_array($product->ProductID, $notAllowed)) {
        $deleteNode = dom_import_simplexml($product);
        $deleteNode->parentNode->removeChild($deleteNode);
    }
}

第二种方法是只选择要删除的节点,这涉及构建XPath表达式,例如...

//Product[ProductID='ZZ-DS' or ProductID='ZZAI-100' or ...]

所以这只是将ID列表与其他适当的位内插的情况,然后是删除所有匹配节点的情况...

$notAllowedList = implode("' or ProductID='", $notAllowed);
$products = $xml->xpath("//Product[ProductID='".$notAllowedList."']");
foreach($products as $product) {
    $deleteNode = dom_import_simplexml($product);
    $deleteNode->parentNode->removeChild($deleteNode);
}