2

我想用属性长度转换 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>
4

2 回答 2

1

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

<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>
于 2012-06-19T04:28:45.023 回答
0

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

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

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

于 2012-06-18T20:44:14.990 回答