未使用Xalan Pipeline扩展在XSLT中复制Schemalocations

时间:2012-08-21 15:25:59

标签: xml xslt xalan

我得到了带有“xsi:schemaLocation =”location1 location2 ...“的xml文件以及很多”xmlns:someNs“。 虽然命名空间将被复制到新文档中,但schemaLocations却没有,我真的无法弄清楚它们被删除的原因(所有namesspaces和schemaLocations也在我的样式表中)。

谷歌表示,如果不在docuent或类似内容中使用它们将被删除,我必须自己添加它们但好像我似乎无法...我正在使用xalan管道管道一些基本的转换,现在我试图在管道的末尾添加样式表,只是再次添加位置。这是我的最后一张:

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

<xsl:template match="/*">
    <xsl:attribute name="xsi:schemaLocation">
      <xsl:text>MYLOCATION</xsl:text>
    </xsl:attribute>

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

</xsl:template>

我有几个带有元素标签的变体没有副本......最好的结果是一个带有schemaLocation的双根元素和一个带有所有命名空间的元素我真的无法解决这个问题。

感谢您的帮助;)

€: 似乎除了xalan管之外,我所有的样式表都在工作。

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:pipe="http://xml.apache.org/xalan/PipeDocument"
                extension-element-prefixes="pipe"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                xsi:schemaLocation="someschema"
              >

  <xsl:param name="source"/>
  <xsl:param name="target"/>

  <!-- I think this block has no effect -->
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="/">

    <pipe:pipeDocument 
          source="{$source}"
          target="{$target}">
      <stylesheet href="sheet1.xsl"/>
      <stylesheet href="sheet2.xsl"/>
      <stylesheet href="sheet3.xsl"/>
    </pipe:pipeDocument>

  </xsl:template>

</xsl:stylesheet>

不再使用-IN和-OUT调用Xalan,我认为这就是我丢失位置的地方,虽然我不明白为什么xmlns声明仍然在输出中。如果在没有管道的情况下使用,每张工作表都会进行自己的身份转换,并按预期工作。

1 个答案:

答案 0 :(得分:3)

不清楚为什么xsi:schemaLocation属性从输出中消失,主要是因为您没有显示输入数据,输出数据或从该输入产生该输出的模板。

您显示的模板无法生成您描述的结果,因为它们根本无法产生任何结果。 (我怀疑你为了简洁而编辑了它们,这一般是一个好主意,但你已经走得太远了。)匹配/*的模板试图编写一个属性,输出中没有任何元素被打开;如果这个模板的某些变体有效,但产生了一个加倍的根元素,我猜这是因为你在模板中有两个xsl:copy元素。

从身份样式表的工作版本开始,我希望您会看到命名空间声明和xsi:schemaLocation属性都出现在输出中。

例如,请考虑此样式表(省略注释和处理说明的模板):

<xsl:stylesheet 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  version="1.0">
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

将其应用于此输入:

<test 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:foo="http://example.com/foo"
  xmlns:bar="http://example.com/bar"
  xsi:schemaLocation="http://example.com/foo foo.xsd
                      http://example.com/bar nss/bar.xsd">
  <data/>
</test>

我得到的结果是:

<test 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:foo="http://example.com/foo" 
  xmlns:bar="http://example.com/bar" 
  xsi:schemaLocation="
    http://example.com/foo foo.xsd
    http://example.com/bar nss/bar.xsd">
  <data/>
</test>

xsi:schemaLocation在那里。名称空间声明在那里。如果它们不在现有样式表的输出中,那么一步一步地将此工作代码更改为更像现有代码。当架构位置属性和/或命名空间停止出现在输出中时,您已找到错误。

如果我不得不猜测,我猜你的现有样式表会删除xsi:schemaLocation属性,因为你没有一个模板可以在输入中匹配它,和/或因为模板那个匹配其父级不包括xsl:apply-templatesselect="@*"