在WSO2 ESB 4.0.3中移除含空子元素的XML元素
Got it, let's work through this problem step by step. You're running a pass-through proxy in WSO2 ESB that pulls data from a DSS endpoint, and some of the returned XML has empty child elements—you need to remove the parent elements that contain these empty children. Here are two straightforward, reliable approaches to implement this:
Approach 1: Use the XSLT Mediator (Most Flexible)
XSLT is ideal for XML transformation tasks like this. You'll create a stylesheet that copies valid nodes but excludes any <Product> elements with empty child nodes.
Step 1: Create the XSLT Stylesheet
Save this as remove-empty-child-elements.xslt and place it in your ESB's repository/resources/xslt directory:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:prod="http://wso2.host.com/Products"> <!-- Identity template: copies all nodes by default --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- Remove <Product> elements that contain any empty child elements (including whitespace-only) --> <xsl:template match="prod:Product[.//*[not(node()) or normalize-space(.) = '']]"/> <!-- Optional: If you want to remove empty child elements instead of their parent <Product>, use this template --> <!-- <xsl:template match="*[not(node()) or normalize-space(.) = '']"/> --> </xsl:template>
- The identity template ensures all valid nodes are preserved.
- The second template targets
<Product>elements (using the correct namespace) that have any child nodes which are empty or contain only whitespace.
Step 2: Add the XSLT Mediator to Your Proxy
Insert the XSLT Mediator into your proxy's outSequence (after fetching data from the DSS endpoint):
<proxy name="ProductProxy" startOnLoad="true" transports="http https" xmlns="http://ws.apache.org/ns/synapse"> <target> <inSequence> <!-- Your existing in-sequence logic (e.g., send request to DSS) --> <send> <endpoint> <address uri="http://your-dss-endpoint-url"/> </endpoint> </send> </inSequence> <outSequence> <!-- Apply the XSLT transformation to clean the response --> <xslt key="remove-empty-child-elements.xslt"/> <send/> </outSequence> </target> </proxy>
Approach 2: Use the Script Mediator (JavaScript)
If you prefer a programmatic approach, use the Script Mediator with JavaScript to inspect and remove problematic elements directly.
Add this Script Mediator to your proxy's outSequence:
<script language="js"><![CDATA[ var payload = mc.getPayloadXML(); var productNS = "http://wso2.host.com/Products"; var products = payload.getElementsByTagNameNS(productNS, "Product"); var markedForRemoval = []; // Check each Product for empty child elements for (var i = 0; i < products.length; i++) { var product = products[i]; var childElements = product.getElementsByTagName("*"); var hasEmptyChild = false; for (var j = 0; j < childElements.length; j++) { var child = childElements[j]; // Check if child is empty (no content or only whitespace) var childContent = child.textContent.trim(); if (childContent === "") { hasEmptyChild = true; break; } } if (hasEmptyChild) { markedForRemoval.push(product); } } // Remove all marked Product elements from the payload for (var k = 0; k < markedForRemoval.length; k++) { markedForRemoval[k].parentNode.removeChild(markedForRemoval[k]); } // Update the payload with cleaned XML mc.setPayloadXML(payload); ]]></script>
- This script iterates over each
<Product>, checks for empty child elements, marks problematic products, then removes them from the response payload.
Key Notes
- Namespace Handling: Always use the correct namespace (
http://wso2.host.com/Products) in both approaches—this ensures you target the right elements. - Edge Cases: Test with scenarios like elements containing only whitespace, or empty elements with attributes, and adjust the logic if needed.
- Alternative Behavior: If you want to remove empty child elements instead of their parent
<Product>, switch to the optional template in the XSLT approach or modify the script to delete child elements directly.
内容的提问来源于stack exchange,提问作者chazbot7

