c# - 如何使用 C# 将具有属性长度的 xml 空元素标记转换为开始标记和结束标记?

标签 c# xml xslt

我想转换带有属性长度的xml空元素标签

<tag length=”3”/>xxxxxxx

分为开始标签和结束标签

<tag>xxx</tag>xxxx

使用 C# 或 XSLT

你有想法吗?

来自:

    <comment>
      <opinion id="tag_1" length="93"/>
      Un bon traiteur Findi Traiteur propose un choix de 
      <topicInstance id="tag_2" length="13"/>
      pâtes cuites à la minute et d'
      <topicInstance id="tag_3" length="9"/>
      antipasti.
    </comment>

收件人:

    <comment>
      <opinion id="tag_1">
      Un bon traiteur Findi Traiteur propose un choix de 
      <topicInstance id="tag_2">
      pâtes cuites</topicInstance> à la minute et d'
      <topicInstance id="tag_3">
      antipasti</topicInstance>.
      </opinion>
    </comment>

最佳答案

这是一个实现所需处理的完整而简单的转换:

<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:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="*[@length]">
  <xsl:variable name="vFollowingText" select=
  "normalize-space(following-sibling::text()[1])"/>

  <xsl:copy>
   <xsl:apply-templates select="@*[not(name()='length')]"/>
   <xsl:value-of select="substring($vFollowingText, 1, @length)"/>
   <xsl:apply-templates/>
  </xsl:copy>
  <xsl:value-of select="substring($vFollowingText, @length+1)"/>
 </xsl:template>

 <xsl:template match="text()[preceding-sibling::*[1][@length]]"/>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时:

<comment>
    <opinion id="tag_1" length="93"/>
    Un bon traiteur Findi Traiteur propose un choix de        
    <topicInstance id="tag_2" length="13"/>
    pâtes cuites à la minute et d'       
    <topicInstance id="tag_3" length="9"/>
    antipasti.     
</comment>

产生了想要的、正确的结果:

<comment>
  <opinion id="tag_1">Un bon traiteur Findi Traiteur propose un choix de</opinion><topicInstance id="tag_2">pâtes cuites </topicInstance>à la minute et d'<topicInstance id="tag_3">antipasti</topicInstance>.</comment>

更新:

根据@enguerran 的评论,<opinion>应该包含其余内容,这里是执行此操作的转换:

<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:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="*[@length]" mode="following">
  <xsl:variable name="vFollowingText" select=
  "normalize-space(following-sibling::text()[1])"/>

  <xsl:copy>
   <xsl:apply-templates select="@*[not(name()='length')]"/>
   <xsl:value-of select="substring($vFollowingText, 1, @length)"/>
   <xsl:apply-templates/>
  </xsl:copy>
  <xsl:value-of select="substring($vFollowingText, @length+1)"/>
 </xsl:template>

 <xsl:template match="*[@length and not(preceding-sibling::*/@length)]">
  <xsl:copy>
   <xsl:apply-templates select="@*[not(name()='length')]"/>
   <xsl:apply-templates select="node()"/>
   <xsl:apply-templates mode="following" select=
    "following-sibling::text()[1] |following-sibling::*" />
  </xsl:copy>
 </xsl:template>
 <xsl:template match="*[preceding-sibling::*[1][@length]] | text()"/>
</xsl:stylesheet>

当此转换应用于所提供的 XML 文档(如上)时,会产生所需的正确结果:

<comment>
<opinion id="tag_1">
      Un bon traiteur Findi Traiteur propose un choix de
      <topicInstance id="tag_2">pâtes cuites </topicInstance>à la minute et d'<topicInstance id="tag_3">antipasti</topicInstance>.</opinion>
</comment>

关于c# - 如何使用 C# 将具有属性长度的 xml 空元素标记转换为开始标记和结束标记?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11086704/

相关文章:

c# - 防止在应用程序的单独实例之间进行拖放操作

xml - 如何从 Delphi Prism 中的 XML 模式生成 Pascal 代码?

xslt 比较两个不同的节点然后合并

xml - 减少 XSLT 1.0 中的重复表达式

c# - 如何在 C# 中将格式化的数字打印到屏幕上?

c# - 在 C# 中获取上/下周星期三日期

c# - LINQ 分组依据不起作用

.net - .NET 中的 XML 代码注释

javascript - 火狐插件 : What is the best way to insert a large chunk of HTML?

xslt - XPATH选择整个树,仅包括第一棵