【问题标题】:Schemalocations not copied in XSLT with Xalan Pipeline extensionXalan Pipeline 扩展未在 XSLT 中复制模式位置
【发布时间】:2012-08-21 15:25:59
【问题描述】:

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

Google 表示,如果在文档中不使用它们或类似的东西,它们将被删除,我必须自己添加它们,但似乎我不能......我正在使用 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 声明仍在输出中。每张工作表都有自己的身份转换,如果不使用管道,则可以按预期工作。

【问题讨论】:

    标签: xml xslt xalan


    【解决方案1】:

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

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

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

    例如,考虑这个样式表(它省略了 cmets 和处理指令的模板):

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

    【讨论】:

    • 问题似乎出在 xalan 管道上,因为所有 Fragment 本身都按预期工作。但是一旦它们被管道化,命名空间就会被消除。我会将其编辑为我原来的问题。
    猜你喜欢
    • 2010-12-26
    • 2013-12-18
    • 2011-06-03
    • 2012-03-23
    • 1970-01-01
    • 2011-03-12
    • 1970-01-01
    • 1970-01-01
    • 2019-07-22
    相关资源
    最近更新 更多