2

Visual Studioを使用して開発中に変換を実行すると、結果のxmlには、テンプレートの基準に一致しないタグに含まれていた宛先のソースxmlからのテキストが含まれます

最初のテンプレートで選択したGroupが、 CrystalReportの直接の子であるGroupという名前の要素を見つけて、それらをapplytemplate呼び出しで渡すことを期待していました。2番目のテンプレートの一致フィルターは、 Level = 1の属性を持つグループのみを取り込み、それらを書き出すことを理解しました。他のすべては無視されると思います。

「これではない」が出力に表示されるのはなぜですか?

ソース

<?xml version="1.0" encoding="utf-8" ?>
<!--
 UPDATE: Note that adding the xmlns attribute causes all output
 to disappear unless you use Chris's second solution.
 -->
<CrystalReport xmlns="urn:crystal-reports:schemas:report-detail" >
  <Group Level="1">
    <GroupHeader>
      <Section>
        <Field FieldName="apple" />
      </Section>
    </GroupHeader>
    <Group Level="2">
      not this
    </Group>
  </Group>
</CrystalReport>

変身

<?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:strip-space elements="*"/>

  <xsl:template match="/CrystalReport">
    <root>
        <xsl:apply-templates select="Group"/>
    </root>
  </xsl:template>

  <xsl:template match="Group[@Level='1']/GroupHeader">
    <tag1><xsl:value-of select="Section/Field/@FieldName"/></tag1>
  </xsl:template>
</xsl:stylesheet>

出力

<?xml version="1.0" encoding="utf-8"?>
<root>
  <tag1>apple</tag1>
      not this
    </root>
4

2 に答える 2

2

XMLパーサーの組み込みテンプレートが機能するという問題に直面しています。すべてのGroup要素にテンプレートを適用していますが、独自のテンプレートでそれらの1つだけをキャッチしています。もう1つは、すべてのノードの値を出力するデフォルトのテンプレートによって処理されます。変更することをお勧めします

 <xsl:template match="/CrystalReport">

の中へ

 <xsl:template match="/">

これにより、追加の出力を生成しているルートのデフォルトテンプレートが上書きされます。組み込みのテンプレートルールの詳細については、http://www.w3.org/TR/xslt#built-in-ruleを参照してください。

次に、基本的なtext()テンプレートをオーバーライドして、最終的なXSLTが次のようになるようにします。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
    <root>
        <xsl:apply-templates select="CrystalReport/Group"/>
    </root>
</xsl:template>
<xsl:template match="Group[@Level='1']/GroupHeader">
    <tag1>
        <xsl:value-of select="Section/Field/@FieldName"/>
    </tag1>
</xsl:template>
<xsl:template match="text()"/>

アップデート

または、さらに簡単に、目的の要素を一致させて、次のようなものを使用することもできます

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/CrystalReport">
    <root>
        <xsl:apply-templates select="Group[@Level='1']/GroupHeader"/>
    </root>
</xsl:template>
<xsl:template match="GroupHeader">
    <tag1>
        <xsl:value-of select="Section/Field/@FieldName"/>
    </tag1>
</xsl:template>

これにより、デフォルトのtext()テンプレートがそのまま残り、非常に便利になります。

于 2012-04-11T10:25:51.877 に答える
0

試す

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:crystal="urn:crystal-reports:schemas:report-detail">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/crystal:CrystalReport">
    <root>
        <xsl:apply-templates select="crystal:Group[@Level='1']/crystal:GroupHeader"/>
    </root>
</xsl:template>
<xsl:template match="crystal:GroupHeader">
    <tag1>
        <xsl:value-of select="crystal:Section/crystal:Field/@FieldName"/>
    </tag1>
</xsl:template>

于 2012-04-11T11:27:58.713 に答える