我需要根据xpath动态转换两个xml。 例如。 我有源xml,看起来像:
<Source>
<ZeroLine>
<FirstLine>
<Name>Name1</Name>
<SurName>SurName1</SurName>
</FirstLine>
<FirstLine>
<Name>Name2</Name>
<SurName>SurName2</SurName>
</FirstLine>
</ZeroLine>
<ZeroLine>
<FirstLine>
<Name>Name3</Name>
<SurName>SurName3</SurName>
</FirstLine>
<FirstLine>
<Name>Name4</Name>
<SurName>SurName4</SurName>
</FirstLine>
</ZeroLine>
</Source>
我需要将此源xml转换为目标xml,它可以具有不同的结构。此目标xml结构基于xPath构建。
目标xml可以看起来像像这样:
<Target>
<TargetZeroLine>
<TargetFirstLine>
<NameIdentifikator>Name1</NameIdentifikator>
<SurNameIdentifikator>SurName1</SurNameIdentifikator>
</TargetFirstLine>
<TargetFirstLine>
<NameIdentifikator>Name2</NameIdentifikator>
<SurNameIdentifikator>SurName2</SurNameIdentifikator>
</TargetFirstLine>
</TargetZeroLine>
<TargetZeroLine>
<TargetFirstLine>
<NameIdentifikator>Name3</NameIdentifikator>
<SurNameIdentifikator>SurName3</SurNameIdentifikator>
</TargetFirstLine>
<TargetFirstLine>
<NameIdentifikator>Name4</NameIdentifikator>
<SurNameIdentifikator>SurName4</SurNameIdentifikator>
</TargetFirstLine>
</TargetZeroLine>
</Target>
此示例的XPath规则是:
源XPath - &gt;目标Xpath
Source / ZeroLine / FirstLine / Name - &gt;目标/ TargetZeroLine / TargetFirstLine / NameIdentifikator
Source / ZeroLine / FirstLine / SurName - &gt;目标/ TargetZeroLine / TargetFirstLine / SurNameIdentifikator
我只有源xml(xsd)和这些xpaths规则,我需要动态构建xslt转换,这将创建目标xml。
我可以手动编写这个xslt,它可以像我想的那样工作,但我需要根据不同的xPaths规则动态构建它。对于此示例,xslt转换如下所示:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="Source">
<xsl:element name="Target">
<xsl:apply-templates select="ZeroLine"/>
</xsl:element>
</xsl:template>
<xsl:template match="ZeroLine">
<xsl:element name="TargetZeroLine">
<xsl:apply-templates select="FirstLine"/>
</xsl:element>
</xsl:template>
<xsl:template match="FirstLine">
<xsl:element name="TargetFirstLine">
<xsl:element name="NameIdentifikator">
<xsl:value-of select="Name"/>
</xsl:element>
<xsl:element name="SurNameIdentifikator">
<xsl:value-of select="SurName"/>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
我的问题是什么? :)问题是如何从xPath为目标构建xslt。当我知道目标xml应该是什么样子时,我可以手动编写这个模板。
E.g。我可以为这个XPath手动编写xslt模板:
Target/TargetZeroLine/TargetFirstLine/NameIdentifikator
它是:
<xsl:template match="FirstLine">
<xsl:element name="TargetFirstLine">
<xsl:element name="NameIdentifikator">
<xsl:value-of select="Name"/>
</xsl:element>
</xsl:element>
</xsl:template>
但是如何编写动态生成此xslt的C#代码?因为我不知道哪个xsl:element ...应该生成哪些模板。
或者问题也可以是:是否可以根据xPath编写xslt xsl:element?我的意思是这样的:
<xsl:template match="FirstLine">
<xsl:element name="Target/TargetZeroLine/TargetFirstLine">
<xsl:element name="NameIdentifikator">
我希望,我的问题可以清楚地理解。
源和目标之间的XPath规则可能不同。层次结构的级别也可以不同。例如。以下XPath规则:
Source/ZeroLine/FirstLine/Name -> Target/NameSection/NameIdentifikator
Source/ZeroLine/FirstLine/SurName -> Target/SurNameSection/SurNameIdentifikator
应生成以下预期的xml:
<Target>
<NameSection>
<NameIdentifikator>Name1</NameIdentifikator>
<NameIdentifikator>Name2</NameIdentifikator>
<NameIdentifikator>Name3</NameIdentifikator>
<NameIdentifikator>Name4</NameIdentifikator>
</NameSection>
<SurNameSection>
<SurNameIdentifikator>SurName1</SurNameIdentifikator>
<SurNameIdentifikator>SurName2</SurNameIdentifikator>
<SurNameIdentifikator>SurName3</SurNameIdentifikator>
<SurNameIdentifikator>SurName4</SurNameIdentifikator>
</SurNameSection>
</Target>
感谢。
答案 0 :(得分:0)
您可以使用XPath选择元素名称,只需将查询与{}
重叠,例如:
<xsl:element name="{Target/TargetZeroLine/TargetFirstLine/NameIdentifikator}">
答案 1 :(得分:0)
也许你在这里过于复杂。仅查看输入XML和输出XML,然后编写XSLT样式表的一种方法如下
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="Source">
<Target>
<xsl:apply-templates />
</Target>
</xsl:template>
<xsl:template match="ZeroLine">
<TargetZeroLine>
<xsl:apply-templates />
</TargetZeroLine>
</xsl:template>
<xsl:template match="FirstLine">
<TargetFirstLine>
<xsl:apply-templates />
</TargetFirstLine>
</xsl:template>
<xsl:template match="Name">
<NameIdentifikator>
<xsl:apply-templates />
</NameIdentifikator>
</xsl:template>
<xsl:template match="SurName">
<SurNameIdentifikator>
<xsl:apply-templates />
</SurNameIdentifikator>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
正如您所看到的,它并不真正担心元素的层次结构或位置。您希望重命名的每个单独元素都有一个模板。
正如您可能看到的,这导致每个模板具有相同的结构。
<xsl:template match="### INPUT ELEMENT ###">
<### OUTPUT ELEMENT ###>
<xsl:apply-templates />
</### OUTPUT ELEMENT ###>
</xsl:template>
所以,如果你真的想写一些C#来为你生成XSLT,你可以简单地用占位符定义一个常量,就像这样
public const string TEMPLATE = @"<xsl:template match="{0}">
<{1}>
<xsl:apply-templates />
</{1}>
</xsl:template>";
然后,假设你有一些方法将源元素名称链接到目标元素名称,你可以做这样的事情
output.WriteLine(string.Format(TEMPLATE, sourceElement, targetElement));