1

タイトルを説明するのは本当に難しいので、私が持っているものを教えてください:

私の XML はもともとフラット ファイルでしたが、操作できるように XML に変換されました。以下は、元の XML を少し簡略化したものです。

<Elements>
    <ElementBegin value="e1"/>
    <ElementBegin value="e2"/>
    <String>Some Blabla</String>
    <ElementEnd value="e2"/>
    <ElementBegin value="e2"/>
    <String>Some other Blabla</String>
    <ElementEnd value="e2"/>
    <ElementBegin value="e5"/>
    <String>Some more Blabla</String>
    <ElementEnd value="e5"/>
    <ElementEnd value="e1"/>
</Elements>

正規表現などを使用して単純に「名前<ElementBegin value="e1"/>を変更」する方法はありますか? または、機能する他のアプローチはありますか?<e1><ElementEnd value="e1"/></e1>

したがって、最終結果は次のようになります

<Elements>
   <e1>
      <e2>
         <String>Some Blabla</String>
      </e2>
      <e2>
         <String>Some other Blabla</String>
      </e2>
      <e5>
         <String>Some more Blabla</String>
      </e5>
   </e1>
</Elements>

前もって感謝します!

4

4 に答える 4

3

XSLT を使用して要素の名前を変更するだけでは、正規表現は必要ありません。次のようなことが簡単にできます。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes"/>

  <!-- Identity transform -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- Drop @value attribute -->
  <xsl:template match="@value"/>

  <!-- Rename <ElementBegin> and <ElementEnd> -->
  <xsl:template match="ElementBegin | ElementEnd">
    <!-- Use the value of the @value attribute as the new element name -->
    <xsl:element name="{@value}">
      <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

ただし、入力 XML と達成したい内容との間には多少の不一致があります。上記のスタイルシートを使用すると、次の結果が得られます。

<?xml version="1.0"?>
<Elements>
<e1/>
 <e2/>
  <String>Some Blabla</String>
 <e2/>
 <e2/>
  <String>Some other Blabla</String>
 <e2/>
 <e5/>
  <String>Some more Blabla</String>
 <e5/>
<e1/>
</Elements>

これは、あなたが探しているものではないと思います。適切なネストを実現するには、もう少し複雑なスタイルシートが必要です。次のようなものが動作するはずです (XSLT1.0 互換):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes"/>

  <!-- Copy <String> elements as is -->
  <xsl:template match="String">
    <xsl:copy>
      <xsl:value-of select="."/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="Elements">
    <xsl:copy>
      <!-- Apply the first <ElementBegin> element -->
      <xsl:apply-templates select="ElementBegin[1]"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="ElementBegin">
    <!-- Use the value of the @value attribute as the new element name -->
    <xsl:element name="{@value}">
      <!--
      Apply String elements whose first preceding <ElementBegin>
      sibling is the current element
      -->
      <xsl:apply-templates select="following-sibling::String
        [preceding-sibling::ElementBegin[1]
          [generate-id() = generate-id(current())]]"/>
    </xsl:element>
  </xsl:template>

  <!--
  Process <ElementBegin value="e1">. You could also use "ElementBegin[1]".
  -->
  <xsl:template match="ElementBegin[@value = 'e1']">
    <xsl:element name="{@value}">
      <!-- Apply all following <ElementBegin> siblings -->
      <xsl:apply-templates select="following-sibling::ElementBegin"/>
    </xsl:element>
  </xsl:template>

  <!-- Drop <ElementEnd> elements -->
  <xsl:template match="ElementEnd"/>
</xsl:stylesheet>

出力

<?xml version="1.0"?>
<Elements>
  <e1>
    <e2>
      <String>Some Blabla</String>
    </e2>
    <e2>
      <String>Some other Blabla</String>
    </e2>
    <e5>
      <String>Some more Blabla</String>
    </e5>
  </e1>
</Elements>
于 2013-03-05T11:04:14.250 に答える
2

xslt についてはわかりませんが、正規表現を使用すると、このタスクを非常に簡単に実行できます。Perl 構文を使用した例を次に示します。

s|<ElementBegin value="(\w+)"/>|<$1>|g;
s|<ElementEnd value="(\w+)"/>|</$1>|g;
于 2013-03-05T10:24:16.357 に答える
2
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>

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

  <xsl:template match="ElementBegin">
    <xsl:value-of select="concat('&#60;', @value,'&#62;')" disable-output-escaping="yes"/>
  </xsl:template>
  <xsl:template match="ElementEnd">
    <xsl:value-of select="concat('&#60;/', @value,'&#62;')" disable-output-escaping="yes"/>
  </xsl:template>
</xsl:stylesheet>

説明:

 <xsl:template match="ElementBegin">
        <xsl:value-of select="concat('&#60;', @value,'&#62;')" disable-output-escaping="yes"/>
      </xsl:template>

上記のテンプレートは、要素名が @value の新しい開始タグを作成します。
例:<e1>

と..

<xsl:template match="ElementEnd">
    <xsl:value-of select="concat('&#60;/', @value,'&#62;')" disable-output-escaping="yes"/>
  </xsl:template>

このコードは、属性値の値として要素名を持つ新しい閉じたタグを作成します。
例:</e1>

したがって、出力 XML は次のようになります。

<Elements>
   <e1>
      <e2>
         <String>Some Blabla</String>
      </e2>
      <e2>
         <String>Some other Blabla</String>
      </e2>
      <e5>
         <String>Some more Blabla</String>
      </e5>
   </e1>
</Elements>
于 2013-03-05T11:21:23.513 に答える
1

Begin と End を組み合わせた正規表現のワンライナー:

<Element(?|Begin[^"]+"(\w+)"\/()|End[^"]+"(\w+)"(\/))と置き換えます<\2\1

ここで説明されたデモ: http://regex101.com/r/nA9rA8

于 2013-03-05T11:12:40.403 に答える