如何修改XSL自动提取带ml:Descriptor属性的XML节点值至DataFrame
需求说明
现有XML结构通过XSL结合pd.read_xml已转换为目标Pandas DataFrame,现在需要修改XSL,实现无需硬编码节点名称,自动识别Meal节点下所有带ml:Descriptor属性的子节点,提取该属性值作为DataFrame对应列的值,适配未来新增的同类型节点。
原XML示例
<ml:Meals xmlns:ml="http://www.food.com"> <ml:Meal> <ml:type>lunch</ml:type> <ml:main_course>turkey sandwich</ml:main_course> <ml:desert ml:Descriptor="cookie"> <ml:ID ml:type="ID">d47e8bb7876e10001d05b9ca33070215</ml:ID> </ml:desert> </ml:Meal> </ml:Meals>
目标DataFrame
+-----+---------------+------+ | type| main_course|desert| +-----+---------------+------+ |lunch|turkey sandwich|cookie| +-----+---------------+------+
原执行命令
pandaDf = pd.read_xml(mealSample, namespaces={"ml": "http://www.food.com"}, stylesheet=xsl)
修改后的XSL方案
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ml="http://www.food.com"> <!-- 基础复制模板,保留原有节点结构 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 处理Meal节点,自动提取带ml:Descriptor属性的子节点 --> <xsl:template match="ml:Meal"> <xsl:copy> <!-- 复制不带ml:Descriptor属性的常规子节点 --> <xsl:copy-of select="*[not(@ml:Descriptor)]"/> <!-- 遍历所有带目标属性的子节点,动态生成对应列节点 --> <xsl:for-each select="*[@ml:Descriptor]"> <xsl:element name="{local-name()}"> <xsl:value-of select="@ml:Descriptor"/> </xsl:element> </xsl:for-each> </xsl:copy> </xsl:template> </xsl:stylesheet>
核心逻辑说明
- 保留常规字段:先复制
Meal节点下所有不带ml:Descriptor属性的子节点(如type、main_course),确保原有正常字段不受影响。 - 自动匹配目标节点:通过
*[@ml:Descriptor]匹配所有带目标属性的子节点,无需硬编码节点名称(比如原有的desert)。 - 动态生成列:用
local-name()获取原节点的本地名称(去掉命名空间前缀)作为新节点名,将ml:Descriptor属性值作为节点文本。未来新增的同类型节点(如<ml:drink ml:Descriptor="cola"/>)会自动生成对应DataFrame列,无需修改XSL。
效果验证
使用修改后的XSL执行原命令,得到的DataFrame与目标完全一致;若新增带ml:Descriptor属性的子节点,DataFrame会自动新增对应列并填充属性值。
内容的提问来源于stack exchange,提问作者daniel9x
相关产品推荐
相关产品推荐

