使用XSLT将XML值拆分为新的XML
本文关键字:XML 拆分 XSLT 使用 | 更新日期: 2023-09-27 17:59:42
是否可以使用XSLT或C#从
<XML>
<Name>Name1;Name2</Name>
<Adress>Adress1;Adress2</Adress>
</XML>
到此
<XML>
<LINE>
<Name>Name1</Name>
<Adress>Adress1</Adress>
</LINE>
<LINE>
<Name>Name2</Name>
<Adress>Adress2</Adress>
</LINE>
</XML>
任何帮助都将不胜感激。
此XSLT2.0转换:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<xsl:copy>
<xsl:variable name="vTop" select="."/>
<xsl:variable name="vAddresses" select="tokenize(Adress, ';')"/>
<xsl:for-each select="tokenize(Name, ';')">
<xsl:variable name="vPos" select="position()" as="xs:integer"/>
<xsl:apply-templates select="$vTop/Name">
<xsl:with-param name="pNameData" select="."/>
<xsl:with-param name="pAdrData" select="$vAddresses[$vPos]"/>
</xsl:apply-templates>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="Name">
<xsl:param name="pNameData"/>
<xsl:param name="pAdrData"/>
<Line>
<Name><xsl:value-of select="$pNameData"/></Name>
<Adress><xsl:value-of select="$pAdrData"/></Adress>
</Line>
</xsl:template>
</xsl:stylesheet>
应用于所提供的XML文档时:
<XML>
<Name>Name1;Name2</Name>
<Adress>Adress1;Adress2</Adress>
</XML>
生成所需的正确结果:
<XML>
<Line>
<Name>Name1</Name>
<Adress>Adress1</Adress>
</Line>
<Line>
<Name>Name2</Name>
<Adress>Adress2</Adress>
</Line>
</XML>
这里有一个非常简单的XSLT1.0解决方案:
输入文件:
<XML>
<Name>Name1;Name2</Name>
<Address>Address1;Address2</Address>
<Name>Name3;Name4</Name>
<Address>Address3;Address4</Address>
</XML>
样式表:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="XML">
<XML>
<xsl:apply-templates select="Name"/>
</XML>
</xsl:template>
<xsl:template match="Name" mode="name-address">
<xsl:param name="name" select="substring-before(., ';')"/>
<xsl:param name="address" select="substring-before(following-sibling::*[1][self::Address], ';')"/>
<LINE>
<Name>
<xsl:value-of select="$name"/>
</Name>
<Address>
<xsl:value-of select="$address"/>
</Address>
</LINE>
</xsl:template>
<xsl:template match="Name">
<xsl:apply-templates select="." mode="name-address"/>
<xsl:apply-templates select="." mode="name-address">
<xsl:with-param name="name" select="substring-after(., ';')"/>
<xsl:with-param name="address" select="substring-after(following-sibling::*[1][self::Address], ';')"/>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
输出:
<?xml version="1.0" encoding="UTF-8"?>
<XML>
<LINE>
<Name>Name1</Name>
<Address>Address1</Address>
</LINE>
<LINE>
<Name>Name2</Name>
<Address>Address2</Address>
</LINE>
<LINE>
<Name>Name3</Name>
<Address>Address3</Address>
</LINE>
<LINE>
<Name>Name4</Name>
<Address>Address4</Address>
</LINE>
</XML>
我不知道XSLT,但如果可能的话,可能会有一个非常复杂的解决方案。
不过,在C#中,它相当简单。这里有一种方法(使用LINQ到XML):
var inputXml =
@"<XML>
<Name>Name1;Name2</Name>
<Adress>Adress1;Adress2</Adress>
</XML>";
var inputXmlDoc = XDocument.Parse(inputXml);
var names = inputXmlDoc.Root.Descendants("Name").Single().Value.Split(';');
var addresses = inputXmlDoc.Root.Descendants("Adress").Single().Value.Split(';');
var outputXmlDoc = new XDocument(
new XElement("XML",
names.Zip(addresses, (n, a) => new {n, a})
.Select(pair => new XElement("LINE",
new XElement("Name", pair.n),
new XElement("Address", pair.a)
))
)
);
Console.WriteLine(outputXmlDoc);