4

次のような XML ファイルがあり、それを別の XML ファイルに変換したいと考えています。

<body>
  <outline text="A">
    <outline text="Abelson, Harold" author="Harold Abelson" title="Struktur und Interpretation von Computerprogrammen. Eine Informatik-Einführung" publisher="Springer Verlag" isbn="3540520430" year="1991"/>
    <outline text="Abrahams, Paul W." author="Paul W. Abrahams" title="Tex for the Impatient" publisher="Addison-Wesley Pub Co" isbn="0201513757" year="2000"/>
  </outline>
  <outline text="B">
    <outline text="Bach, Fred" author="Fred Bach" title="UNIX Handbuch zur Programmentwicklung" publisher="Hanser Fachbuchverlag" isbn="3446151036"/>
    <outline text="Bach, Maurice J." author="Maurice J. Bach" title="Design of the UNIX Operating System" publisher="Prentice Hall PTR" isbn="0132017997" year="1986"/>
  </outline>
</body>

変換したいXML形式は次のとおりです

<list>
    <books text="A">
        <book>
            <text>Abelson, Harold</text>
            <author>Harold Abelson</author>
            <title>Struktur und Interpretation von Computerprogrammen. Eine
                Informatik-Einführung</title>
            <publisher>Springer Verlag</publisher>
            <isbn>3540520430</isbn>
            <year>1991</year>
        </book>
        <book>
            <text>Abrahams, Paul W.</text>
            <author>Paul W. Abrahams</author>
            <title>Tex for the Impatient</title>
            <publisher>Addison-Wesley Pub Co</publisher>
            <isbn>0201513757</isbn>
            <year>2000</year>
        </book>

    </books>
    <books text="B">
        <book>
            <text>Bach, Fred</text>
            <author>Fred Bach</author>
            <title>UNIX Handbuch zur Programmentwicklung</title>
            <publisher>Hanser Fachbuchverlag</publisher>
            <isbn>3446151036</isbn>
            <year />
        </book>

これが私のコードです

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="xml"/>
    <xsl:template match="body">
        <list> <xsl:apply-templates select="outline"/> </list>
    </xsl:template>

    <xsl:template match="outline">
    <books text= "{@text}">
        <book><xsl:apply-templates select="outline"/> 
        <text><xsl:value-of select="@text" /></text>
        <author><xsl:value-of select="@author" /></author>
        <title><xsl:value-of select="@title" /></title>
        <publisher><xsl:value-of select="@publisher" /></publisher>
        <isbn><xsl:value-of select="@isbn" /></isbn>
        <year><xsl:value-of select="@year" /></year>
        </book>
    </books>
    </xsl:template>


</xsl:stylesheet>

これが私のコードの出力です。

<list>
    <books text="A">
        <book>
            <books text="Abelson, Harold">
                <book>
                    <text>Abelson, Harold</text>
                    <author>Harold Abelson</author>
                    <title>Struktur und Interpretation von Computerprogrammen. Eine
                        Informatik-Einführung</title>
                    <publisher>Springer Verlag</publisher>
                    <isbn>3540520430</isbn>
                    <year>1991</year>
                </book>
            </books>

私の出力には2つの余分な要素があります

<books text="Abelson, Harold">
                <book>

私の知る限り、これはこのコード行が原因である可能性があります。私はいくつかの異なる方法を試しましたが、うまくいきませんでした

<xsl:template match="outline">
        <books text= "{@text}">

追加の質問: 元の XML ファイルにタイトルが含まれている場合。頭と称号の消し方。私の現在のコードは、新しい XML ファイルで「tmp」を生成します。

<opml version="1.0">
  <head>
    <title>tmp</title>
    <expansionState></expansionState>
  </head>
  <body>
      <outline text="A">
      <outline text="Abelson, Harold" author="H
4

3 に答える 3

3

あなたは正しい道を歩んでいましたが、2 つのoutlineテンプレートが必要です。outlineoutlines

outlineテンプレートを次の 3 つに置き換えてください。

  <xsl:template match="head" />

  <xsl:template match="outline">
    <books text="{@text}">
      <xsl:apply-templates select="outline" />
    </books>
  </xsl:template>

  <xsl:template match="outline/outline">
    <book>
      <text>
        <xsl:value-of select="@text" />
      </text>
      <author>
        <xsl:value-of select="@author" />
      </author>
      <title>
        <xsl:value-of select="@title" />
      </title>
      <publisher>
        <xsl:value-of select="@publisher" />
      </publisher>
      <isbn>
        <xsl:value-of select="@isbn" />
      </isbn>
      <year>
        <xsl:value-of select="@year" />
      </year>
    </book>
  </xsl:template>

また、ソース ドキュメントの属性の名前が出力ドキュメントの要素の名前と一致すると安全に想定できる場合は、その 2 番目のテンプレートを次の 2 つの短くて合理化されたものに置き換えることができます。

  <xsl:template match="outline/outline">
    <book>
      <xsl:apply-templates select="@text" />
      <xsl:apply-templates select="@author" />
      <xsl:apply-templates select="@title" />
      <xsl:apply-templates select="@publisher" />
      <xsl:apply-templates select="@isbn" />
      <xsl:apply-templates select="@year" />
    </book>
  </xsl:template>

  <xsl:template match="outline/outline/@*">
    <xsl:element name="{name()}">
       <xsl:value-of select="." />
    </xsl:element>
  </xsl:template>
于 2013-01-23T07:10:53.107 に答える
3

はるかに短い完全なソリューション:

<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="/*"><list><xsl:apply-templates/></list></xsl:template>

 <xsl:template match="outline">
    <books text="{@text}">
      <xsl:apply-templates/>
    </books>
  </xsl:template>

  <xsl:template match="outline/outline">
    <book><xsl:apply-templates select="@*"/></book>
  </xsl:template>

  <xsl:template match="outline/outline/@*">
      <xsl:element name="{name()}">
        <xsl:value-of select="." />
      </xsl:element>
  </xsl:template>
</xsl:stylesheet>

この変換が提供された XML ドキュメントに適用されると、次のようになります。

<body>
  <outline text="A">
    <outline text="Abelson, Harold" author="Harold Abelson" title="Struktur und Interpretation von Computerprogrammen. Eine Informatik-Einführung" publisher="Springer Verlag" isbn="3540520430" year="1991"/>
    <outline text="Abrahams, Paul W." author="Paul W. Abrahams" title="Tex for the Impatient" publisher="Addison-Wesley Pub Co" isbn="0201513757" year="2000"/>
  </outline>
  <outline text="B">
    <outline text="Bach, Fred" author="Fred Bach" title="UNIX Handbuch zur Programmentwicklung" publisher="Hanser Fachbuchverlag" isbn="3446151036"/>
    <outline text="Bach, Maurice J." author="Maurice J. Bach" title="Design of the UNIX Operating System" publisher="Prentice Hall PTR" isbn="0132017997" year="1986"/>
  </outline>
</body>

必要な正しい結果が生成されます。

<list>
 <books text="A">
   <book>
      <text>Abelson, Harold</text>
      <author>Harold Abelson</author>
      <title>Struktur und Interpretation von Computerprogrammen. Eine Informatik-Einführung</title>
      <publisher>Springer Verlag</publisher>
      <isbn>3540520430</isbn>
      <year>1991</year>
   </book>
   <book>
      <text>Abrahams, Paul W.</text>
      <author>Paul W. Abrahams</author>
      <title>Tex for the Impatient</title>
      <publisher>Addison-Wesley Pub Co</publisher>
      <isbn>0201513757</isbn>
      <year>2000</year>
   </book>
 </books>
 <books text="B">
   <book>
      <text>Bach, Fred</text>
      <author>Fred Bach</author>
      <title>UNIX Handbuch zur Programmentwicklung</title>
      <publisher>Hanser Fachbuchverlag</publisher>
      <isbn>3446151036</isbn>
   </book>
   <book>
      <text>Bach, Maurice J.</text>
      <author>Maurice J. Bach</author>
      <title>Design of the UNIX Operating System</title>
      <publisher>Prentice Hall PTR</publisher>
      <isbn>0132017997</isbn>
      <year>1986</year>
   </book>
 </books>
<list>

説明:

  1. テンプレートと一致パターンの適切な使用。

  2. の適切な使用<xsl:element>


Ⅱ.生成された要素の特定の順序が必要な場合 (ソース属性の順序は保証できないため)、次のわずかな変更を使用します

<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="/*"><list><xsl:apply-templates/></list></xsl:template>

 <xsl:template match="outline">
    <books text="{@text}">
      <xsl:apply-templates/>
    </books>
  </xsl:template>

  <xsl:template match="outline/outline">
    <book>
      <xsl:apply-templates select="@*">
        <xsl:sort data-type="number" select=
          string-length(substring-before('text|author|title|publisher|isbn|year',name()))"/>
      </xsl:apply-templates></book>
  </xsl:template>

  <xsl:template match="outline/outline/@*">
      <xsl:element name="{name()}">
        <xsl:value-of select="." />
      </xsl:element>
  </xsl:template>
</xsl:stylesheet>
于 2013-01-23T12:58:11.740 に答える
3

これは、ソース XML から結果 XML に要素を手動でプルすることにあまり依存しない、もう少しプッシュ指向のソリューションです。特に、最後のテンプレートに注目してください。

この 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="/*">
    <list>
      <xsl:apply-templates />
    </list>
  </xsl:template>

  <xsl:template match="outline[outline]">
    <books text="{@text}">
      <xsl:apply-templates />
    </books>
  </xsl:template>

  <xsl:template match="outline[not(*)]">
    <book>
      <xsl:apply-templates select="@*" />
    </book>
  </xsl:template>

  <xsl:template match="outline[not(*)]/@*">
    <xsl:element name="{name()}">
      <xsl:value-of select="." />
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

...提供されたソース XML に対して適用されます。

<body>
  <outline text="A">
    <outline text="Abelson, Harold" author="Harold Abelson" title="Struktur und Interpretation von Computerprogrammen. Eine Informatik-Einführung" publisher="Springer Verlag" isbn="3540520430" year="1991"/>
    <outline text="Abrahams, Paul W." author="Paul W. Abrahams" title="Tex for the Impatient" publisher="Addison-Wesley Pub Co" isbn="0201513757" year="2000"/>
  </outline>
  <outline text="B">
    <outline text="Bach, Fred" author="Fred Bach" title="UNIX Handbuch zur Programmentwicklung" publisher="Hanser Fachbuchverlag" isbn="3446151036"/>
    <outline text="Bach, Maurice J." author="Maurice J. Bach" title="Design of the UNIX Operating System" publisher="Prentice Hall PTR" isbn="0132017997" year="1986"/>
  </outline>
</body>

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

<list>
  <books text="A">
    <book>
      <text>Abelson, Harold</text>
      <author>Harold Abelson</author>
      <title>Struktur und Interpretation von Computerprogrammen.
        Eine Informatik-Einführung</title>
      <publisher>Springer Verlag</publisher>
      <isbn>3540520430</isbn>
      <year>1991</year>
    </book>
    <book>
      <text>Abrahams, Paul W.</text>
      <author>Paul W. Abrahams</author>
      <title>Tex for the Impatient</title>
      <publisher>Addison-Wesley Pub Co</publisher>
      <isbn>0201513757</isbn>
      <year>2000</year>
    </book>
  </books>
  <books text="B">
    <book>
      <text>Bach, Fred</text>
      <author>Fred Bach</author>
      <title>UNIX Handbuch zur Programmentwicklung</title>
      <publisher>Hanser Fachbuchverlag</publisher>
      <isbn>3446151036</isbn>
    </book>
    <book>
      <text>Bach, Maurice J.</text>
      <author>Maurice J. Bach</author>
      <title>Design of the UNIX Operating System</title>
      <publisher>Prentice Hall PTR</publisher>
      <isbn>0132017997</isbn>
      <year>1986</year>
    </book>
  </books>
</list>
于 2013-01-23T08:55:34.617 に答える