You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取XML叶子节点的完整层级路径及对应值?

XML叶子节点完整路径提取方案

问题背景

给定一段XML结构代码,需要提取所有叶子节点的完整层级路径(从根节点下一级开始,以.分隔),并输出路径与对应节点值的映射,格式为路径 值。

给定XML代码片段

<Profile>
    <Settings>
        <PresentationParameters>
            <Annualize>True</Annualize>
            <LoadExAnteRiskForPresentation>False</LoadExAnteRiskForPresentation>
            <MultiLegDisplayMode>Legs</MultiLegDisplayMode>
            <Parameters>
                <InitialDisplayMode>CollapseToPositions</InitialDisplayMode>
                <InitialExpandCollapseLevel>-1</InitialExpandCollapseLevel>
            </Parameters>
            <PivotExpandCollapseStrategy>ExpandAllStrategy</PivotExpandCollapseStrategy>
            <RollupExternallyManagedSleeves>False</RollupExternallyManagedSleeves>
            <SharedParameters>
                <AssetBasisInEffect>
                    <CalculationType>Invalid</CalculationType>
                    <IsColumnBasisInvested>False</IsColumnBasisInvested>
                    <Type>Standard</Type>
                    <Value>MWB_SESSION</Value>
                </AssetBasisInEffect>
                <AssetBasisSaveable>
                    <CalculationType>Invalid</CalculationType>
                    <IsColumnBasisInvested>False</IsColumnBasisInvested>
                    <Type>Standard</Type>
                    <Value>MWB_SESSION</Value>
                </AssetBasisSaveable>
                <CurrencySaveable>
                    <Mode>GROUP</Mode>
                </CurrencySaveable>
                <IsSessionBasisInEffect>True</IsSessionBasisInEffect>
            </SharedParameters>
            <ShowPositionsGrandTotal>True</ShowPositionsGrandTotal>
            <TargetingCurrency>
                <Mode>GROUP</Mode>
            </TargetingCurrency>
            <TransposeColumns>False</TransposeColumns>
            <UnitBasisMeasureOption>PercentagePoints</UnitBasisMeasureOption>
            <UnitTrustConstituentMode>DoNotDisplay</UnitTrustConstituentMode>
            <WeightProrationOption>Default</WeightProrationOption>
        </PresentationParameters>
    </Settings>
</Profile>

期望输出格式

Settings.PresentationParameters.Annualize  TRUE
Settings.PresentationParameters.LoadExAnteRiskForPresentation  FALSE
Settings.PresentationParameters.MultiLegDisplayMode Legs
Settings.PresentationParameters.Parameters.InitialDisplayMode  CollapseToPositions
Settings.PresentationParameters.Parameters.InitialExpandCollapseLevel  -1
Settings.PresentationParameters.PivotExpandCollapseStrategy  ExpandAllStrategy
Settings.PresentationParameters.RollupExternallyManagedSleeves  FALSE
Settings.PresentationParameters.SharedParameters.AssetBasisInEffect.CalculationType  Invalid
Settings.PresentationParameters.SharedParameters.AssetBasisInEffect.IsColumnBasisInvested  FALSE
Settings.PresentationParameters.SharedParameters.AssetBasisInEffect.Type  Standard
Settings.PresentationParameters.SharedParameters.AssetBasisInEffect.Value  MWB_SESSION
Settings.PresentationParameters.SharedParameters.AssetBasisSaveable.CalculationType  Invalid
Settings.PresentationParameters.SharedParameters.AssetBasisSaveable.IsColumnBasisInvested  FALSE
Settings.PresentationParameters.SharedParameters.AssetBasisSaveable.Type  Standard
Settings.PresentationParameters.SharedParameters.AssetBasisSaveable.Value  MWB_SESSION
Settings.PresentationParameters.SharedParameters.CurrencySaveable.Mode  GROUP
Settings.PresentationParameters.SharedParameters.IsSessionBasisInEffect  TRUE
Settings.PresentationParameters.ShowPositionsGrandTotal  TRUE
Settings.PresentationParameters.TargetingCurrency.Mode  GROUP
Settings.PresentationParameters.TransposeColumns  FALSE
Settings.PresentationParameters.UnitBasisMeasureOption  PercentagePoints
Settings.PresentationParameters.UnitTrustConstituentMode  DoNotDisplay
Settings.PresentationParameters.WeightProrationOption  Default

实现方案

1. Python 实现(使用标准库xml.etree.ElementTree)

核心思路:递归遍历XML节点,判断当前节点是否为叶子节点(无直接子元素),若是则从父节点开始拼接完整路径,最后输出路径和节点文本值(可按需转换大小写)。

import xml.etree.ElementTree as ET

def get_leaf_paths(element, current_path=""):
    # 拼接当前节点到路径中
    new_path = f"{current_path}.{element.tag}" if current_path else element.tag
    # 判断是否为叶子节点:无直接子元素
    if len(element) == 0:
        # 去除根节点Profile,只保留Settings开始的路径
        if new_path.startswith("Profile."):
            output_path = new_path[len("Profile."):]
        else:
            output_path = new_path
        # 转换值为大写(按需调整)
        value = element.text.strip().upper() if element.text else ""
        print(f"{output_path}  {value}")
    else:
        # 递归遍历子节点
        for child in element:
            get_leaf_paths(child, new_path)

# 解析XML(可替换为fromstring直接解析XML字符串)
tree = ET.parse("profile.xml")
root = tree.getroot()

# 开始遍历
get_leaf_paths(root)

2. Java 实现(使用DOM解析)

核心思路:通过DOM解析XML,递归遍历节点,记录当前层级路径,遇到叶子节点时输出路径和值。

import org.w3c.dom.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;

public class XMLLeafPathExtractor {
    public static void main(String[] args) {
        try {
            File xmlFile = new File("profile.xml"); // 替换为你的XML文件路径
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(xmlFile);
            doc.getDocumentElement().normalize();

            traverseNode(doc.getDocumentElement(), "");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void traverseNode(Node node, String currentPath) {
        if (node.getNodeType() == Node.ELEMENT_NODE) {
            Element element = (Element) node;
            String newPath = currentPath.isEmpty() ? element.getTagName() : currentPath + "." + element.getTagName();
            NodeList childNodes = element.getChildNodes();
            boolean isLeaf = true;

            // 判断是否为叶子节点:子节点中没有其他元素节点
            for (int i = 0; i < childNodes.getLength(); i++) {
                Node child = childNodes.item(i);
                if (child.getNodeType() == Node.ELEMENT_NODE) {
                    isLeaf = false;
                    traverseNode(child, newPath);
                }
            }

            if (isLeaf) {
                // 去除根节点Profile
                if (newPath.startsWith("Profile.")) {
                    String outputPath = newPath.substring("Profile.".length());
                    String value = element.getTextContent().trim().toUpperCase();
                    System.out.println(outputPath + "  " + value);
                }
            }
        }
    }
}

3. PowerShell 实现

核心思路:使用Select-Xml结合XPath表达式//*[not(*)]筛选所有叶子节点,再通过节点的ParentNode属性回溯拼接完整路径。

# 读取XML文件
$xml = [xml](Get-Content "profile.xml") # 替换为你的XML文件路径

# 筛选所有叶子节点(无子元素的元素)
$leafNodes = Select-Xml -Xml $xml -XPath "//*[not(*)]"

foreach ($node in $leafNodes) {
    $pathParts = @()
    $currentNode = $node.Node

    # 回溯父节点,拼接路径
    while ($currentNode -ne $xml.Profile) {
        $pathParts += $currentNode.Name
        $currentNode = $currentNode.ParentNode
    }

    # 反转路径顺序,拼接为正常层级
    $path = ($pathParts | Reverse) -join "."
    $value = $node.Node.InnerText.Trim().ToUpper()
    Write-Output "$path  $value"
}

内容的提问来源于stack exchange,提问作者NoazDad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 10:47:06