0

我得到了带有“xsi:schemaLocation =”location1 location2 ...”和很多“xmlns:someNs”的xml文件。虽然命名空间将被复制到新文档中,但schemaLocations不是,我真的不知道为什么它们被删除(所有命名空间和 schemaLocations 也在我的样式表中)。

谷歌表示,当不在文档或类似的东西中使用它们时,它们将被删除,我必须自己添加它们,但似乎我不能......我正在使用 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>

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

4

1 回答 1

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="@*".

于 2012-08-21T16:54:29.117 回答