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>

更新

<opinion>残りのコンテンツを囲む必要がある @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 ドキュメント (上記) に適用されると、必要な正しい結果が生成されます。

<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 に答える