c# - Flatten xml with text and element nodes using LINQ to XML -
i need process/flatten incoming xml in fashion.
source xml:
<paragraph> <content stylecode="underline">is</content> <content stylecode="italic"> <content stylecode="underline"> <content stylecode="bold">hello</content> world </content> test</content> <content stylecode="bold">example</content> here. </paragraph>
target xml:
<paragraph> <content stylecode="underline">is</content> <content stylecode="italic underline bold">hello</content> <content stylecode="italic underline">world</content> <content stylecode="italic">test</content> <content stylecode="bold">example</content> here. </paragraph>
i prefer use linq xml realize children text nodes next content
element nodes make different task now.
another idea had use regular expression combine innerxml @ every step inserting closing </content>
before child node , opening <content>
after it, update stylecode attributes accordingly, addbeforeself
, remove old node. have not succeeded idea either.
any ideas, solutions appreciated.
besides combining , flattening content
nodes, have lowercase combined stylecode attributes, that's easiest part obviously:
xdocument xml = xdocument.parse(sourcexml); xname contentnode = xname.get("content", "mynamespace"); var contentnodes = xml.descendants(contentnode); var renames = contentnodes.where(x => x.attribute("stylecode") != null); foreach (xelement node in renames.toarray()) { node.attribute("stylecode").value = node.attribute("stylecode").value.tolower(); }
you can recursively - go node node collecting styles, when comes text, wrap content tag tags found far. code below:
static void mergestyles(string xml) { xdocument doc = xdocument.parse(xml); var desc = doc.document.elements(); go(doc.root, new list<string>()); console.writeline(target); } static string target = ""; static void go(xelement node, list<string> styles) { foreach (var child in node.nodes()) { if (child.nodetype == xmlnodetype.text) { if (styles.count > 0) { target += string.format( "<content stylecode=\"{0}\">{1}</content>", string.join(" ", styles.select(s => s.tolower())), child.tostring(saveoptions.disableformatting)); } else { target += child.tostring(saveoptions.disableformatting); } } else if (child.nodetype == xmlnodetype.element) { var element = (xelement)child; if (element.name == "content") { string style = element.attributes("stylecode").single().value; styles.add(style); go(element, styles); styles.removeat(styles.count - 1); } } } }
Comments
Post a Comment