0

私は次のような非友好的で中途半端なxmlファイルの強打を持っています:

<root>
<child0><name0>Bob Dylan</name0></child0>
<child1><name1>Daft Punk</name1></child1>
<child2><name2>Nine Inch Nails</name2></child2>
</root>

そして私は各ファイルを次のように変換したいと思います:

<root><children>
<child><name>Bob Dylan</name></child>
<child><name>Daft Punk</name></child>
<child><name>Nine Inch Nails</name></child> 
</children>
</root>

各ファイルには、決定論的な数の子はありません。他の人が持っている間だけ持って<child0>いる人もい<child0> ... <child10>ます。子内の要素も決定されていません。name[0]など。

だから私は、常に子と子の子要素を終了している数字と一致するように、各子(おそらくワイルドカードまたはends-with、または??)をウォークスルーしたいと思います。

これは機能しませんが、次のようなものです。

<xsl:for-each select="child*" >
     <child>
     <name><xsl:value-of select="name[index]"></name>
     </child>
</xsl:for-each>

要素(または位置やインデックスによる要素)内のコンテンツの選択を処理するselect、if、およびmatch条件の例をたくさん見てきました...それが実行されるべき方法だからです。

しかし、私は有効でありながら中途半端なxmlを持っています。

4

2 に答える 2

2

これは、あなたが望むことを達成する、単純でプッシュ指向のソリューションです。XSLT /XPath1.0または2.0のいずれかを使用して動作することに注意してください。

このXSLTの場合:

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

  <xsl:template match="/*">
    <root>
      <children>
        <xsl:apply-templates />
      </children>
    </root>
  </xsl:template>

  <xsl:template match="*[starts-with(name(), 'child')]">
    <child>
      <xsl:apply-templates />
    </child>
  </xsl:template>

  <xsl:template match="*[starts-with(name(), 'name')]">
     <name>
       <xsl:apply-templates />
     </name>
  </xsl:template>

</xsl:stylesheet>

...元のXMLに適用されます:

<root>
  <child0>
    <name0>Bob Dylan</name0>
  </child0>
  <child1>
    <name1>Daft Punk</name1>
  </child1>
  <child2>
    <name2>Nine Inch Nails</name2>
  </child2>
</root>

...必要な結果が生成されます:

<root>
  <children>
    <child>
      <name>Bob Dylan</name>
    </child>
    <child>
      <name>Daft Punk</name>
    </child>
    <child>
      <name>Nine Inch Nails</name>
    </child>
  </children>
</root>
于 2012-12-01T22:56:05.440 に答える
0

これを行う簡単な方法は、name()値に正規表現を使用することです。

<xsl:for-each select="*[matches(name(),'^child\d$')]">
...
于 2012-12-01T21:35:35.843 に答える