与Saxon 9.2兼容的问题他

时间:2011-08-17 15:24:37

标签: xslt

我有一个带有saxon 9.2的xslt文件的问题。 (xslt文件在xslt 1.0中工作,引擎包含在c#中,但速度太慢了)

Xslt文件

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

  <xsl:template match="Magasins">
    <Magasins xmlns:xi="http://www.w3.org/2001/XInclude" Id="{@Id}">
      <xsl:apply-templates/>
    </Magasins>
  </xsl:template>

  <xsl:key name="kClientGroup" match="Client"
      use="concat(../@CodeRouteur, @ComplementCodeRouteur)"
        />

  <xsl:template match="Magasin">
<xsl:apply-templates select="Client[generate-id() 
        =
        generate-id(key('kClientGroup', 
        concat(../@CodeRouteur, @ComplementCodeRouteur))[1])]"
        />
  </xsl:template>

  <xsl:template match="Client">
    <Magasin
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        CodeRouteur="{concat(../@CodeRouteur,@ComplementCodeRouteur)}">

      <xsl:copy-of select="../@*[name() != 'CodeRouteur']"/>

      <xsl:apply-templates select="key('kClientGroup', 
                concat(../@CodeRouteur,@ComplementCodeRouteur))" mode="copy"/>

    </Magasin>
  </xsl:template>

  <xsl:template match="Client" mode="copy">
    <xsl:copy>
      <xsl:copy-of select="node()|@*"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Xml源文件

<?xml version="1.0" encoding="UTF-8"?>
<Magasins>
  <Magasin Nom="Name" CodeRouteur="TE">
    <Client IdClient="1" ComplementCodeRouteur="A" Name="YYY"><Elem /></Client>
    <Client IdClient="2" ComplementCodeRouteur="B" Name="XXX"><Elem /></Client>
  </Magasin>
  <Magasin Nom="Name2" CodeRouteur="TE">
    <Client IdClient="3" ComplementCodeRouteur="A" Name="YYY"><Elem /></Client>
  </Magasin>
</Magasins>

想要的输出文件

<?xml version="1.0" encoding="UTF-8"?>
<Magasins>
  <Magasin Nom="Name" CodeRouteur="TEA">
    <Client IdClient="1" ComplementCodeRouteur="A" Name="YYY"><Elem /></Client>
  </Magasin>
  <Magasin Nom="Name" CodeRouteur="TEB">
    <Client IdClient="2" ComplementCodeRouteur="B" Name="XXX"><Elem /></Client>
  </Magasin>
  <Magasin Nom="Name2" CodeRouteur="TEA">
    <Client IdClient="3" ComplementCodeRouteur="A" Name="YYY"><Elem /></Client>
  </Magasin>
</Magasins>

但每次我在Magasin或Client内部使用@ComplementCodeRouteur等属性时,它都不会返回任何内容。唯一有效的属性是Magasins中的Id = {@ Id}。 有人知道为什么以及如何解决它? 我不够好找到它为什么不起作用。

2 个答案:

答案 0 :(得分:1)

我尝试从命令行使用Saxon 9.3.0.5 Java运行您的示例,输出如下:

Warning: at xsl:stylesheet on line 2 column 81 of test2011081702.xsl:
  Running an XSLT 1 stylesheet with an XSLT 2 processor
<?xml version="1.0" encoding="UTF-8"?>
<Magasins xmlns:xi="http://www.w3.org/2001/XInclude" Id="">
  <Magasin xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            CodeRouteur="TEA"
            Nom="Name">
      <Client IdClient="1" ComplementCodeRouteur="A" Name="YYY">
         <Elem/>
      </Client>
      <Client IdClient="3" ComplementCodeRouteur="A" Name="YYY">
         <Elem/>
      </Client>
   </Magasin>
   <Magasin xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            CodeRouteur="TEB"
            Nom="Name">
      <Client IdClient="2" ComplementCodeRouteur="B" Name="XXX">
         <Elem/>
      </Client>
   </Magasin>

</Magasins>

对我来说这看起来很好(尽管它会在你发布的样本中没有显示一些分组)。您可能使用的.NET版本是否真的会给您带来不同的结果?你如何用.NET运行转换?

[edit]我现在也从命令行尝试过.NET版本的Saxon 9.3,它也输出

Warning: at xsl:stylesheet on line 2 column 81 of test2011081702.xsl:
  Running an XSLT 1 stylesheet with an XSLT 2 processor
<?xml version="1.0" encoding="UTF-8"?>
<Magasins xmlns:xi="http://www.w3.org/2001/XInclude" Id="">
  <Magasin xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            CodeRouteur="TEA"
            Nom="Name">
      <Client IdClient="1" ComplementCodeRouteur="A" Name="YYY">
         <Elem/>
      </Client>
      <Client IdClient="3" ComplementCodeRouteur="A" Name="YYY">
         <Elem/>
      </Client>
   </Magasin>
   <Magasin xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            CodeRouteur="TEB"
            Nom="Name">
      <Client IdClient="2" ComplementCodeRouteur="B" Name="XXX">
         <Elem/>
      </Client>
   </Magasin>

</Magasins>

答案 1 :(得分:1)

这个简化的样式表:

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

  <xsl:template match="/">
    <Magasins>
      <xsl:apply-templates/>
    </Magasins>
  </xsl:template>

  <xsl:template match="Magasin">
    <xsl:apply-templates select="Client"/>
   </xsl:template>

  <xsl:template match="Client">
    <Magasin Nom="{../@Nom}"
         CodeRouteur="{concat(../@CodeRouteur,@ComplementCodeRouteur)}">
      <xsl:apply-templates select="." mode="copy"/>
    </Magasin>
  </xsl:template>

  <xsl:template match="*" mode="copy">
    <xsl:copy>
      <xsl:copy-of select="node()|@*"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

生成此输出:

$ java -jar c:/Java/saxon92/saxon9he.jar magasin.xml magasin2.xsl
Warning: at xsl:stylesheet on line 2 column 81 of magasin2.xsl:
  Running an XSLT 1.0 stylesheet with an XSLT 2.0 processor
<?xml version="1.0" encoding="UTF-8"?>
<Magasins>
  <Magasin Nom="Name" CodeRouteur="TEA">
      <Client IdClient="1" ComplementCodeRouteur="A" Name="YYY">
         <Elem/>
      </Client>
   </Magasin>
   <Magasin Nom="Name" CodeRouteur="TEB">
      <Client IdClient="2" ComplementCodeRouteur="B" Name="XXX">
         <Elem/>
      </Client>
   </Magasin>
  <Magasin Nom="Name2" CodeRouteur="TEA">
      <Client IdClient="3" ComplementCodeRouteur="A" Name="YYY">
         <Elem/>
      </Client>
   </Magasin>
</Magasins>

这就是你想要的。

所谓的兼容性问题看起来像是一个副问题。没有XSLT处理器会使用问题中显示的样式表生成所需的输出。因此,我建议采用不同的方法来产生输出。