我在 C# 中使用 ExtendedXmlSerializer,一個已知的限制是添加物件的序列化串列。這樣做時,它會產生一個單獨的元素(串列本身),其中包含串列的專案。由于我正在反序列化來自單獨應用程式的外部 xml,因此我無法控制 xml 的布局,因此需要在 C# 中反序列化之前轉換 xml。
將單一型別的元素添加到新的(不存在的)元素中時,我在 stackoverflow 的其他地方找到的轉換作業正常,但在嘗試使用多種不同型別時失敗。
我試圖盡可能地簡化源 xml:
<?xml version="1.0" encoding="utf-8"?>
<Document>
<Engineering version="V16" /> <!-- some other elements besides Engineering as well -->
<SW.Blocks.FB ID="0">
<AttributeList>
<AutoNumber>true</AutoNumber>
<!--more elements including where "Member" is eventually -->
</AttributeList>
<ObjectList>
<MultilingualText ID="1" CompositionName="Comment"/>
<SW.Blocks.CompileUnit ID="D" CompositionName="CompileUnits"/>
<SW.Blocks.CompileUnit ID="26" CompositionName="CompileUnits"/>
<SW.Blocks.CompileUnit ID="3F" CompositionName="CompileUnits"/>
<SW.Blocks.CompileUnit ID="58" CompositionName="CompileUnits"/>
<MultilingualText ID="71" CompositionName="Title"/>
</ObjectList>
</SW.Blocks.FB>
</Document>
首選輸出是這樣的:
<Document>
<Engineering version="V16" />
<!-- some other elements besides Engineering as well -->
<SW.Blocks.FB ID="0">
<AttributeList>
<AutoNumber>true</AutoNumber>
<!--more elements including where "Member" is eventually -->
</AttributeList>
<ObjectList>
<CompileUnitToRemove>
<SW.Blocks.CompileUnit ID="D" CompositionName="CompileUnits" />
<SW.Blocks.CompileUnit ID="26" CompositionName="CompileUnits" />
<SW.Blocks.CompileUnit ID="3F" CompositionName="CompileUnits" />
<SW.Blocks.CompileUnit ID="58" CompositionName="CompileUnits" />
</CompileUnitToRemove>
<MultilingualTextToRemove>
<MultilingualText ID="1" CompositionName="Comment" />
<MultilingualText ID="71" CompositionName="Title" />
</MultilingualTextToRemove>
</ObjectList>
</SW.Blocks.FB>
</Document>
就像我上面所說的那樣,CompileUnitToRemove 和 MultilingualTextToRemove 元素可以使 ExtendedXmlSerializer 與串列一起使用。
我目前的xslt如下:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*"/>
<!-- copy all elements over, except what falls into other template -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- if local name (namespace independent) is 'Member': -->
<xsl:template match="*[local-name(.)='Member']">
<!-- store namespace of Member in variable-->
<xsl:variable name="ns" select="namespace-uri()" />
<xsl:copy>
<xsl:apply-templates select="@*|node()[not(self::*[local-name(.)='SubElement'])]"/>
<!-- copy everything (except Subelements) over and create a new element "SubElements" with same nameSpace as parent (Member) -->
<xsl:element name="SubElements" namespace="{$ns}">
<!-- copy all Subelements over into new element -->
<xsl:apply-templates select="*[local-name(.)='SubElement']"/>
</xsl:element>
</xsl:copy>
</xsl:template>
<!-- works the same as above, but trying with 2 items within ObjectList: -->
<xsl:template match="*[local-name(.)='ObjectList']">
<xsl:variable name="ns" select="namespace-uri()" />
<xsl:copy>
<xsl:apply-templates select="@*|node()[not(self::*[local-name(.)='SW.Blocks.CompileUnit'])]"/>
<xsl:element name="CompileUnitToRemove" namespace="{$ns}">
<xsl:apply-templates select="*[local-name(.)='SW.Blocks.CompileUnit']"/>
</xsl:element>
<xsl:apply-templates select="@*|node()[not(self::*[local-name(.)='MultilingualText'])]"/>
<xsl:element name="MultilingualTextToRemove" namespace="{$ns}">
<xsl:apply-templates select="*[local-name(.)='MultilingualText']"/>
</xsl:element>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
但是,這會創建以下 xml:
<Document>
<Engineering version="V16" />
<!-- some other elements besides Engineering as well -->
<SW.Blocks.FB ID="0">
<AttributeList>
<AutoNumber>true</AutoNumber>
<!--more elements including where "Member" is eventually -->
</AttributeList>
<ObjectList>
<MultilingualText ID="1" CompositionName="Comment" />
<MultilingualText ID="71" CompositionName="Title" />
<CompileUnitToRemove>
<SW.Blocks.CompileUnit ID="D" CompositionName="CompileUnits" />
<SW.Blocks.CompileUnit ID="26" CompositionName="CompileUnits" />
<SW.Blocks.CompileUnit ID="3F" CompositionName="CompileUnits" />
<SW.Blocks.CompileUnit ID="58" CompositionName="CompileUnits" />
</CompileUnitToRemove>
<SW.Blocks.CompileUnit ID="D" CompositionName="CompileUnits" />
<SW.Blocks.CompileUnit ID="26" CompositionName="CompileUnits" />
<SW.Blocks.CompileUnit ID="3F" CompositionName="CompileUnits" />
<SW.Blocks.CompileUnit ID="58" CompositionName="CompileUnits" />
<MultilingualTextToRemove>
<MultilingualText ID="1" CompositionName="Comment" />
<MultilingualText ID="71" CompositionName="Title" />
</MultilingualTextToRemove>
</ObjectList>
</SW.Blocks.FB>
</Document>
如您所見,其中的元素是重復的。
我還嘗試將“xsl:apply-templates”部分放入它自己的“xsl:copy”部分,以及它自己的“<xsl:template match="*[local-name(.)='ObjectList'] ">" 但它要么導致更多重復,要么只是跳過第一個列出的那個。
如果有人可以幫助我弄清楚正確的 xslt 布局需要是什么,將不勝感激。對于 ExtendedXmlSerializer 串列問題,我也可以使用另一種解決方法,但出于其他原因我確實需要 ExtendedXmlSerializer,并且使用 xslt 是開發人員推薦的解決方案。
uj5u.com熱心網友回復:
以下模板是否滿足您的要求?
<xsl:template match="ObjectList">
<ObjectList>
<CompileUnitToRemove>
<xsl:apply-templates select="SW.Blocks.CompileUnit"/>
</CompileUnitToRemove>
<MultilingualTextToRemove>
<xsl:apply-templates select="MultilingualText"/>
</MultilingualTextToRemove>
</ObjectList>
</xsl:template>
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/484389.html
