我的XML如下:
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xmlns:ev="http://www.w3.org/2001/xml-events" xml:lang="de">
<head>
<title>Some Title</title>
<link rel="stylesheet" type="text/css" href="../Styles/9783748258957.css"/>
</head>
<body>
<div id="Inhalt">
<p class="toc-ch"><span class="bi">4 Main Value</span></p>
<p class="toc-h1">4.1 Child Value 1</p>
<p class="toc-h1">4.2 Child Value 2</p>
<p class="toc-h1">4.3 Child Value 3</p>
<p class="toc-h2">4.3.1 Grand-child Value</p>
<p class="toc-h2">4.3.2 Grand-child Value</p>
<p class="toc-h2">4.3.3 Grand-child Value</p>
<p class="toc-h2">4.3.4 Grand-child Value</p>
<p class="toc-h1">4.4 Child Value 4</p>
<p class="toc-h2">4.4.1 Grand-child Value</p>
<p class="toc-h2">4.4.2 Grand-child Value</p>
<p class="toc-h2">4.4.3 Grand-child Value</p>
<p class="toc-h2">4.4.4 Grand-child Value</p>
<p class="toc-h1">4.5 Child Value 5</p>
</div>
</body>
</html>
我希望XML具有以下结构:
<?xml version="1.0" encoding="UTF-8"?>
<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1" xml:lang="de">
<head>
<title>Some Title</title>
<link rel="stylesheet" type="text/css" href="../Styles/9783748258957.css"/>
</head>
<body>
<navMap>
<navPoint id="navPoint-01" playOrder="01"><navLabel><text>4 Main Value</text></navLabel>
<navPoint id="navPoint-02" playOrder="02"><navLabel><text>4.1 Child Value 1</text></navLabel></navPoint>
<navPoint id="navPoint-03" playOrder="03"><navLabel><text>4.2 Child Value 2</text></navLabel></navPoint>
<navPoint id="navPoint-04" playOrder="04"><navLabel><text>4.3 Child Value 3</text></navLabel>
<navPoint id="navPoint-05" playOrder="05"><navLabel><text>4.3.1 Grand-child Value</text></navLabel></navPoint>
<navPoint id="navPoint-06" playOrder="06"><navLabel><text>4.3.2 Grand-child Value</text></navLabel></navPoint>
<navPoint id="navPoint-07" playOrder="07"><navLabel><text>4.3.3 Grand-child Value</text></navLabel></navPoint>
<navPoint id="navPoint-08" playOrder="08"><navLabel><text>4.3.4 Grand-child Value</text></navLabel></navPoint></navPoint>
<navPoint id="navPoint-09" playOrder="09"><navLabel><text>4.4 Child Value 4</text></navLabel>
<navPoint id="navPoint-10" playOrder="10"><navLabel><text>4.4.1 Grand-child Value</text></navLabel></navPoint>
<navPoint id="navPoint-11" playOrder="11"><navLabel><text>4.4.2 Grand-child Value</text></navLabel></navPoint>
<navPoint id="navPoint-12" playOrder="12"><navLabel><text>4.4.3 Grand-child Value</text></navLabel></navPoint>
<navPoint id="navPoint-13" playOrder="13"><navLabel><text>4.4.4 Grand-child Value</text></navLabel></navPoint></navPoint>
<navPoint id="navPoint-14" playOrder="14"><navLabel><text>4.5 Child Value 5</text></navLabel></navPoint></navPoint>
</navMap>
</body>
</ncx>
如何使用foreach
循环实现这一目标?
我想基于class
属性嵌套元素。因此,toc-ch
是主要元素,toc-h1
在toc-ch
之下,而toc-h2
在toc-h1
之下
我无法使其嵌套。现在这只是一个<div id="inhalt">
,我有多个<div>
元素。每个类的结构都相同。
这就是我所做的:
XDocument xtocdoc = XDocument.Load("epubv3TOC.xml");
XNamespace xtocNamespace = xtocdoc.Root.GetDefaultNamespace();
int navPointValue = 1;
int playOrdervalue = 1;
foreach (var value in breakslist)
{
var valueElements = value.Descendants(htmlNamespace + "p").ToList();
foreach (var values in valueElements)
if (values.Attribute("class") != null)
{
if (values.Attribute("class") != null && values.Attribute("class").Value.Contains("ch"))
{
xtocdoc.Descendants(xtocNamespace + "navMap").FirstOrDefault(de => de != null)
.Add(new XElement(xtocNamespace + "navPoint", new XAttribute("id", "navPoint-" + navPointValue)
, new XAttribute("playOrder", playOrdervalue)
, new XElement(xtocNamespace + "navLabel"
, new XElement(xtocNamespace + "text", "ch"))));
continue;
}
else if (values.Attribute("class") != null && values.Attribute("class").Value.Contains("h1"))
{
xtocdoc.Descendants(xtocNamespace + "navMap").FirstOrDefault(de => de != null)
.Elements(xtocNamespace + "navPoint")
.FirstOrDefault(el => el != null)
.Add(new XElement(xtocNamespace + "navPoint", new XAttribute("id", "navPoint-" + navPointValue)
, new XAttribute("playOrder", playOrdervalue)
, new XElement(xtocNamespace + "navLabel"
, new XElement(xtocNamespace + "text", "h1"))));
continue;
}
else if (values.Attribute("class") != null && values.Attribute("class").Value.Contains("h2"))
{
xtocdoc.Descendants(xtocNamespace + "navMap").FirstOrDefault(de => de != null)
.Elements(xtocNamespace + "navPoint")
.FirstOrDefault(el => el != null)
.Add(new XElement(xtocNamespace + "navPoint", new XAttribute("id", "navPoint-" + navPointValue)
, new XAttribute("playOrder", playOrdervalue)
, new XElement(xtocNamespace + "navLabel"
, new XElement(xtocNamespace + "text", "h2"))));
continue;
}
}
}
答案 0 :(得分:1)
要处理嵌套,您需要跟踪当前的顶层navPoint
和当前的子级navPoint
(如果有)。然后,您可以根据class
元素的p
决定在何处添加新元素。
这是一些示例代码。它对标题等没有任何作用-我专注于嵌套:
using System;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
class Program
{
static void Main()
{
var input = XDocument.Load("test.xml");
XNamespace ncx = "http://www.daisy.org/z3986/2005/ncx/";
XNamespace xhtml = "http://www.w3.org/1999/xhtml";
// Skipped creating all the rest of the structure: focusing on the
// navMap
var navMap = new XElement(ncx + "navMap");
var inhalt = input.Descendants(xhtml + "div")
.Single(div => (string) div.Attribute("id") == "Inhalt");
XElement currentTop = null;
XElement currentChild = null;
int index = 1;
foreach (var element in inhalt.Elements())
{
string id = $"navPoint-{index++:00}";
var point = new XElement(ncx + "navPoint", new XAttribute("id", id));
var navLabel = new XElement(ncx + "navLabel", element.Value);
point.Add(navLabel);
// TODO: playOrder attribute, text element etc. They're not important for nesting.
switch (element.Attribute("class")?.Value)
{
case "toc-ch":
currentTop = point;
currentChild = null;
navMap.Add(point);
break;
case "toc-h1":
if (currentTop == null)
{
throw new InvalidOperationException("toc-h1 with no toc-ch");
}
currentChild = point;
currentTop.Add(point);
break;
case "toc-h2":
if (currentChild == null)
{
throw new InvalidOperationException("toc-h2 with no toc-h1");
}
currentChild.Add(point);
break;
default:
throw new InvalidOperationException("Unknown class attribute");
}
}
var output = new XDocument(new XElement(ncx + "ncx", navMap));
var settings = new XmlWriterSettings { Indent = true };
using (var writer = XmlWriter.Create(Console.Out, settings))
{
output.Save(writer);
}
}
}
输出为:
<?xml version="1.0" encoding="ibm850"?>
<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/">
<navMap>
<navPoint id="navPoint-01">
<navLabel>4 Main Value</navLabel>
<navPoint id="navPoint-02">
<navLabel>4.1 Child Value 1</navLabel>
</navPoint>
<navPoint id="navPoint-03">
<navLabel>4.2 Child Value 2</navLabel>
</navPoint>
<navPoint id="navPoint-04">
<navLabel>4.3 Child Value 3</navLabel>
<navPoint id="navPoint-05">
<navLabel>4.3.1 Grand-child Value</navLabel>
</navPoint>
<navPoint id="navPoint-06">
<navLabel>4.3.2 Grand-child Value</navLabel>
</navPoint>
<navPoint id="navPoint-07">
<navLabel>4.3.3 Grand-child Value</navLabel>
</navPoint>
<navPoint id="navPoint-08">
<navLabel>4.3.4 Grand-child Value</navLabel>
</navPoint>
</navPoint>
<navPoint id="navPoint-09">
<navLabel>4.4 Child Value 4</navLabel>
<navPoint id="navPoint-10">
<navLabel>4.4.1 Grand-child Value</navLabel>
</navPoint>
<navPoint id="navPoint-11">
<navLabel>4.4.2 Grand-child Value</navLabel>
</navPoint>
<navPoint id="navPoint-12">
<navLabel>4.4.3 Grand-child Value</navLabel>
</navPoint>
<navPoint id="navPoint-13">
<navLabel>4.4.4 Grand-child Value</navLabel>
</navPoint>
</navPoint>
<navPoint id="navPoint-14">
<navLabel>4.5 Child Value 5</navLabel>
</navPoint>
</navPoint>
</navMap>
</ncx>
答案 1 :(得分:0)
这里是使用Xml Linq的解决方案。.为什么会有两个嵌套级别的navPoint? :
var regex = new RegExp ("^.*\.(mp4)$")
if (regex.test(fileNam)){
// logic here
}