C#通用实现XmlNode转换为键值对属性格式XML的技术咨询
Absolutely! You can pull off this transformation in a generic, scalable way—no hardcoding specific tag names required. The key is using tools or libraries designed for XML manipulation, which let you define rules that apply to any matching structure in your XML. Let’s walk through two reliable approaches:
1. XSLT (Extensible Stylesheet Language Transformations)
XSLT is the gold standard for XML-to-XML transformations, and it’s perfect for this use case because it lets you define generic rules instead of targeting specific tags. Here’s a reusable stylesheet that converts child elements (with only text content) into attributes on their parent element:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- Copy all elements, attributes, and text by default --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- For any element, convert its text-only child elements to attributes --> <xsl:template match="*"> <xsl:copy> <!-- First, add attributes from text-only child elements --> <xsl:for-each select="*[not(*)]"> <xsl:attribute name="{local-name()}"> <xsl:value-of select="normalize-space(.)"/> </xsl:attribute> </xsl:for-each> <!-- Then, process remaining child elements (non-text-only ones) --> <xsl:apply-templates select="*[*]|text()"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
How it works:
- The first template is an "identity transform" that copies everything as-is unless overridden.
- The second template targets all elements:
- It loops through direct child elements that have no child elements of their own (i.e., they’re leaf nodes with just text).
- For each of these, it creates an attribute on the parent element using the child’s tag name as the attribute key, and the child’s text content as the value.
- It then preserves any remaining child elements that have their own children (like your
<item-values>) by applying the identity transform to them.
You can run this stylesheet with any XSLT processor (like xsltproc on Linux/macOS, or tools like Saxon).
2. Python with lxml Library
If you prefer a programmatic approach, Python’s lxml library (a powerful XML parser) lets you write a generic function to handle this transformation. Here’s how:
from lxml import etree def child_nodes_to_attributes(element): # Process children first (recursive to handle nested structures) for child in list(element): if len(child) == 0: # Child has no sub-elements (only text) # Add as attribute to parent element.set(child.tag, child.text.strip() if child.text else "") # Remove the child node from the parent element.remove(child) else: # Recursively process nested elements child_nodes_to_attributes(child) # Load your input XML input_xml = """<variants> <item> <name>sport</name> <description>sport desc</description> <item-values> <item-value> <item>ball</item> <value>stichball</value> </item-value> </item-values> </item> </variants>""" root = etree.fromstring(input_xml) # Apply the transformation child_nodes_to_attributes(root) # Print the output XML print(etree.tostring(root, pretty_print=True, encoding="unicode"))
How it works:
- The
child_nodes_to_attributesfunction recursively traverses every element in the XML tree. - For each child element that has no sub-elements (just text), it adds the child’s tag and text as an attribute to the parent, then deletes the child node.
- Nested elements (like
<item-values>) are processed recursively, so their child nodes (like<item-value>’s children) are also converted to attributes.
Both of these approaches are generic—they’ll work for any XML structure where you want to convert leaf-node children to parent attributes, not just your specific <item> and <item-value> examples.
内容的提问来源于stack exchange,提问作者arunraj770

