XML转换求助:移除pi:AI并按条件替换pi:SD值
Let's work through your XSLT problem step by step. You've got two key goals here—removing all pi:AI nodes, and conditionally updating pi:SD values when pi:C is 402B or 402F—plus you're hitting an issue where variables are coming up empty after adjustments. Let's sort this out.
First, Let's Outline the Solution
The core approach uses XSLT's template matching system: we'll keep most content intact with an identity template, explicitly remove pi:AI nodes, and target the specific pi:SD nodes that need updating.
Here's the XSLT code you can use (make sure to replace the namespace URI with your actual one from the XML):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:pi="http://your-actual-namespace-uri"> <!-- Identity template: copies all nodes/attributes we don't explicitly modify --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- Remove all pi:AI nodes entirely --> <xsl:template match="pi:AI"/> <!-- Update pi:SD when its sibling pi:C is 402B or 402F --> <xsl:template match="pi:SD[../pi:C = '402B' or ../pi:C = '402F']"> <pi:SD> <!-- Grab the IRS value from the same pi:EE's pi:AI node --> <xsl:value-of select="../pi:AI/pi:IRS"/> </pi:SD> </xsl:template> </xsl:stylesheet>
How This Works
- Identity Template: This is the backbone—it copies every node and attribute that isn't matched by another template. That way, all your existing content stays intact except the parts we want to change.
- Removing pi:AI: The template matching
pi:AIdoes nothing when it finds those nodes, so they get dropped from the output entirely. - Conditional pi:SD Update: We target
pi:SDnodes where their siblingpi:Chas the values you care about. We then replace thepi:SD's content with thepi:IRSvalue from the same parent node'spi:AI(even though we're removingpi:AIlater, we can still access its value before it's discarded).
Troubleshooting the "Empty Variable" Issue
If you were getting empty values before, it's almost certainly a path or namespace problem:
- Check Namespaces: Make sure the
piprefix in your XSLT maps to the exact same URI as in your XML. Mismatched namespaces mean XSLT won't find your nodes at all. - Verify Node Hierarchy: If
pi:SDandpi:Caren't direct siblings, orpi:AIis in a different level, adjust the path. For example, ifpi:EEis the grandparent ofpi:SD, useancestor::pi:EE/pi:AI/pi:IRSinstead of../pi:AI/pi:IRS.
Example Input & Output
Let's test with a sample XML to see it in action:
Input XML:
<pi:Root xmlns:pi="http://your-actual-namespace-uri"> <pi:EE> <pi:C>402B</pi:C> <pi:SD>OriginalValue1</pi:SD> <pi:AI> <pi:IRS>ReplacementValue1</pi:IRS> </pi:AI> </pi:EE> <pi:EE> <pi:C>402F</pi:C> <pi:SD>OriginalValue2</pi:SD> <pi:AI> <pi:IRS>ReplacementValue2</pi:IRS> </pi:AI> </pi:EE> <pi:EE> <pi:C>OtherCode</pi:C> <pi:SD>KeepThisValue</pi:SD> <pi:AI> <pi:IRS>IgnoreThis</pi:IRS> </pi:AI> </pi:EE> </pi:Root>
Output XML:
<pi:Root xmlns:pi="http://your-actual-namespace-uri"> <pi:EE> <pi:C>402B</pi:C> <pi:SD>ReplacementValue1</pi:SD> </pi:EE> <pi:EE> <pi:C>402F</pi:C> <pi:SD>ReplacementValue2</pi:SD> </pi:EE> <pi:EE> <pi:C>OtherCode</pi:C> <pi:SD>KeepThisValue</pi:SD> </pi:EE> </pi:Root>
That should hit all your requirements. If your XML has a slightly different structure, just tweak the node paths in the template and it should work!
内容的提问来源于stack exchange,提问作者Carla

