0

为什么以下不能像我期望的那样工作?

<root xmlns:ns0="xmlns" 
      ns0:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:ns1="xsi" 
      ns1:schemaLocation="[some schema location]" />

基本上,我正在尝试通过执行以下操作将 schemaLocation 添加到没有此功能的 xml 文件中:-

<xsl:template match="/s:*">
  <xsl:element name="{local-name()}" namespace="some other namespace">
    <xsl:attribute namespace="xmlns" name="xsi">http://www.w3.org/2001/XMLSchema-instance</xsl:attribute>
    <xsl:attribute namespace="xsi" name="schemaLocation">[some-loc]</xsl-attribute>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:element>
</xsl:template>

Xalan-C 给出了上面显示的 xml。

我想要得到的是这样的: -

<root xmlns:ns0="http://www.w3.org/2001/XMLSchema-instance"
      ns0:schemaLocation="[some schema location]" />
4

2 回答 2

3

你需要<xsl:attribute name="xsi:schemaLocation">[some-loc]</xsl:attribute>.

编辑(添加完整示例):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
   <xsl:template match="root">
      <xsl:element name="{local-name()}" namespace="some other namespace">
         <!--<xsl:attribute namespace="xmlns" name="xsi">http://www.w3.org/2001/XMLSchema-instance</xsl:attribute>-->
         <xsl:attribute name="xsi:schemaLocation">[some-loc]</xsl:attribute>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:element>
   </xsl:template>
</xsl:stylesheet>

根据您正在做什么,您可以使用<xsl:copy>复制元素而不是<xsl:element name="{local-name()}"/>; 它有点简单。

于 2012-09-24T19:23:16.227 回答
3

当我解释您的问题并推断您真正想要的内容时,问题是您正在将一个值放入namespace="..."您打算成为命名空间前缀实际上应该是命名空间 URI的值。

因此,您可能想要的代码只是一个<xsl:attribute>元素:

<xsl:template match="/s:*">
  <xsl:element name="{local-name()}" namespace="some other namespace">
    <xsl:attribute namespace="http://www.w3.org/2001/XMLSchema-instance" 
        name="xsi:schemaLocation">[some-loc]</xsl-attribute>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:element>
</xsl:template>

然后 XSLT 处理器将schemaLocation在正确的名称空间中输出指定的属性,并且还会在需要时为其前缀发出名称空间声明(其前缀可以是xsi:,但不一定是)。

这里的部分问题是人们在不明确他们的意思的情况下(在精神上或对其他人)抛出“命名空间”这个词。命名空间不是命名空间前缀,也不是真正的命名空间 URI。命名空间由其 URI全局标识,并由其前缀在本地标识。

如果 XSLT 规范将这个属性命名为namespace-uri="..."而不是namespace="...",那么就会有更少的人落入这个陷阱。您还可以通过询问说“命名空间”的人是否真的意味着“命名空间 URI”、“命名空间前缀”、“命名空间声明”等来保护自己。

于 2012-09-24T19:23:50.900 回答