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

如何使用C#将具有属性长度的xml空元素标记转换为开始标记和结束标记?,c#,xml,xslt,C#,Xml,Xslt,我想转换具有属性长度的xml空元素标记 <tag length=”3”/>xxxxxxx xxxxxxx 分为开始标记和结束标记 <tag>xxx</tag>xxxx xxxxxxx 使用C#或XSLT 你有主意了吗 发件人: <comment> <opinion id="tag_1" length="93"/> Un bon traiteur Findi Traiteur propose un

我想转换具有属性长度的xml空元素标记

<tag length=”3”/>xxxxxxx
xxxxxxx
分为开始标记和结束标记

<tag>xxx</tag>xxxx
xxxxxxx
使用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>

我们是叛徒,我们是叛徒
一分钟一分钟
安提帕斯蒂。
致:


我们是叛徒,我们是叛徒
一分钟一分钟
安提帕斯蒂。

这可能在某种程度上满足您的要求:

<xsl:template match="comment/opinion|comment/topicInstance">
    <xsl:copy>
        <!-- copy attributes except for "length" -->
        <xsl:for-each select="@*[local-name() != 'length']">
            <xsl:copy/>
        </xsl:for-each>
        <!-- include characters from the following text node -->
        <xsl:value-of select="substring(following-sibling::text()[1], 1, @length)"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="comment/text()">
    <xsl:variable name="previous" select="preceding-sibling::node()[1]"/>
    <!-- strip characters that have been inserted in the previous node -->
    <xsl:value-of select="substring(*, $previous/@length + 1)"/>
</xsl:template>


它不会涵盖所有情况,您需要添加一些检查(例如,检查前一个节点是否存在等)。

下面是一个完整而简单的转换,它实现了所需的处理过程:

<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>
<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>
<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>

在提供的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>

我们是叛徒,我们是叛徒
一分钟一分钟
安提帕斯蒂。
生成所需的正确结果

<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>
<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>
<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>
<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>
<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>
在@enguerran的注释之后,
应该包含其余的内容,下面是一个转换:

<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文档(如上)时,将生成所需的正确结果

<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>
<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>
<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>

我们是叛徒,我们是叛徒
这是一分钟和一分钟的时间。

请给出一个在修改前后显示XML的示例。从什么到什么?你能举个真实的例子吗。(不是XXXX的)你愿意考虑使用XSLT吗?您可以使用
xslcomiledtransform
类将XSLT脚本应用于C#中的XML文档。我怀疑XSLT将是最优雅的解决方案,但如果您不感兴趣,我不会在上面浪费时间。我想使用XSLT,但我有一个相同的问题:我不知道如何检索开始和结束的偏移量。世界上为什么会有人想这样做…?想要的正确结果可能有“意见”节点作为这两个节点的父节点“局部持续性“节点,因为它的长度是93。@enguerran:噢。我明白了。这一要求没有明确说明,因此,在您的评论之前,我没有注意到
意见
必须成为两个
主题实例
元素的父元素。谢谢你提醒我这个事实。当我有时间时,我会看一看,并将实现这一最终要求。@enguerran:要求不明确:如果以下同级文本的总字符串长度小于n 93,应该生成什么?如果字符串总长度大于93,应该生成什么?在没有这些需求的定义的情况下,我不希望仅仅凭猜测就开始任何大的工作。曾经有人决定不关闭xml标记,而是添加一个额外的长度属性来指定xml标记的范围。我们必须断言结束标记必须在偏移量93处。如果没有足够的字符,它将抛出异常/错误。当然,如果总字符串长度大于93,则必须在字符串的中间添加结束标记。但我们必须假设长度是正确的。@enguerran:如果“我们必须假设长度是正确的”,那么生成这个结果就很简单了。