如何返回XML节点的完整层级?

0 投票
3 回答
41 浏览
提问于 2025-04-13 19:41

给定以下的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
...

我在寻找如何获取节点的完整路径的建议。

3 个回答

0

你可以使用 lxml 库,来得到类似的结果,方法是使用 getelementpath()

import lxml.etree as etree

xml_str = """<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>
"""

root = etree.fromstring(xml_str)
tree = etree.ElementTree(root)

for elem in root.iter():
    print(tree.getelementpath(elem), elem.text)
0

既然你提到了XPath,下面这个XPath 3.1的表达式可以完成这个任务:

//*[not(*)] ! 
  ((ancestor-or-self::*/local-name() => string-join('.')) 
    || ' ' || string(.))
3

我希望我理解了这个问题。用Python来解决这个问题的一个可能方法是:

import xml.etree.ElementTree as ET

def dfs(node, path):
    if len(node) == 0:  # If the node is a leaf
        print(f'{path}.{node.tag} {node.text}')
    else:
        for child in node:
            dfs(child, f'{path}.{node.tag}')

xml_string = """<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>
"""
root = ET.fromstring(xml_string)
dfs(root, '')

它会返回以下结果:

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

撰写回答