我想知道是否有办法使用linq转换节点的层次结构到XML或xslt。
我想转型
<hardware>
<software/>
<software/>
</hardware>
<hardware>
<software/>
<software/>
</hardware>
我使用现有的父子关系,只需翻转并重建结构,就像这样。
<software>
<hardware/>
<hardware/>
</software>
<software>
<hardware/>
<hardware/>
</software>
答案 0 :(得分:0)
我想知道是否有办法 使用linq翻转节点的层次结构 到XML或xslt。
。 。 。 。 。 。 。
我使用现有父母的地方 - 孩子的关系,只是翻转和 重建结构。
是。这种转变:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kSoftByName" match="software"
use="@name"/>
<xsl:template match=
"software[generate-id()
=
generate-id(key('kSoftByName',@name)[1])
]
">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates mode="copy"
select="key('kSoftByName',@name)/.."/>
</xsl:copy>
</xsl:template>
<xsl:template match="hardware" mode="copy">
<xsl:copy>
<xsl:copy-of select="@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
应用于此XML文档时:
<inventory>
<hardware name="PC">
<software name="Office"/>
<software name="Safari"/>
<software name="Windows"/>
</hardware>
<hardware name="Mac">
<software name="Safari"/>
<software name="Office"/>
<software name="Leopard"/>
</hardware>
</inventory>
会产生想要的正确结果:
<software name="Office">
<hardware name="PC"/>
<hardware name="Mac"/>
</software>
<software name="Safari">
<hardware name="PC"/>
<hardware name="Mac"/>
</software>
<software name="Windows">
<hardware name="PC"/>
</software>
<software name="Leopard">
<hardware name="Mac"/>
</software>
解释:Muenchian分组方法。
答案 1 :(得分:0)
这是LINQ版本。
给出像这样的xml:
var xml = @"
<inventory>
<hardware name=""PC"">
<software name=""Office""/>
<software name=""Safari""/>
<software name=""Windows""/>
</hardware>
<hardware name=""Mac"">
<software name=""Safari""/>
<software name=""Office""/>
<software name=""Leopard""/>
</hardware>
</inventory>";
以下是将其拆分的查询:
var xd = XDocument.Parse(xml);
var query =
from h in xd.Root.Elements()
from s in h.Elements()
select new
{
hardware = h.Attribute("name").Value,
software = s.Attribute("name").Value
};
var lookup = query.ToLookup(q => q.software, q => q.hardware);
这是将它重新组合在一起的查询,按需要翻转:
var result =
new XDocument
(
new XElement
(
"inventory",
from s in query.Select(q => q.software).Distinct()
select new XElement
(
"software",
new XAttribute("name", s),
from h in lookup[s].Distinct()
select new XElement
(
"hardware",
new XAttribute("name", h)
)
)
)
);
/*
<inventory>
<software name="Office">
<hardware name="PC" />
<hardware name="Mac" />
</software>
<software name="Safari">
<hardware name="PC" />
<hardware name="Mac" />
</software>
<software name="Windows">
<hardware name="PC" />
</software>
<software name="Leopard">
<hardware name="Mac" />
</software>
</inventory>
*/