产生默认命名空间约定的转换xmlns =“...”

时间:2015-06-19 01:09:52

标签: xslt-1.0

给出以下xml:

<root xmlns="example.com">
  <child />
</root>

可以使用xslt(版本1.0)生成:

<newRoot xmlns="stackoverflow.com">
  <child />
</newroot>

我尝试了排除结果前缀和名称空间别名的各种组合。 E.g,

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:e="example.com" xmlns:s="stackoverflow.com" exclude-result-prefixes="e">

<xsl:namespace-alias stylesheet-prefix="s" result-prefix="#default" />

    <xsl:template match="e:root">
        <s:newRoot>
            <xsl:apply-templates />
        </s:newRoot>
    </xsl:template>

    <xsl:template match="e:child">
        <s:child />
    </xsl:template>

</xsl:stylesheet>

我最接近的是以下不正确的xml

<newRoot>
  <child />
</newroot>
编辑:我为过于简单的样本道歉。 我正在搜索的解决方案将更改默认命名空间并将转换为我的xml。这是我想要做的更复杂的例子:

<Data xmlns="sample.com/public">
  <Insured>
    <Name>Sample Client</Name>
    <Locations>
      <Location Number="1">
        <Address>
          <City>New York</City>
          <State>New York</State>
          <Street>222 10 Street</Street>
        </Address>
      </Location>
      <Location Number="2">
        <Address>
          <City>New York</City>
          <State>New York</State>
          <Street>3538 27 Street</Street>
        </Address>
      </Location>
    </Locations>
    <Coverages>
      <LocationSplit>
        <LocationNumber>1</LocationNumber>
        <Clause>
          <Limit>10000000</Limit>
        </Clause>
      </LocationSplit>
    </Coverages>
  </Insured>
</Data>

哪个会成为

<projection xmlns="sample.com/projected">
  <insured>
    <name>Sample Client</name>
    <location address="222 10 Street New York, New York">
      <clause>
        <limit>10000000</limit>
      </clause>
    </location>
  </insured>
</projection>

我认为exclude-result-prefix和namespace-alias是故障单,因为我可以通过在样式表中声明它们来显式使用每个命名空间,然后删除/ public命名空间,同时将/ projection命名空间别名化为#default。但是,别名会导致简单地删除命名空间。

2 个答案:

答案 0 :(得分:1)

如果您只是希望字面匹配输入根并逐字输出结果文档,请执行以下操作:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
                xmlns:ex="example.com"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                exclude-result-prefixes="ex">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/ex:root">
    <newRoot xmlns="stackoverflow.com">
      <child/>
    </newRoot>
  </xsl:template>

</xsl:stylesheet>

虽然有效,但可能会或可能不会满足您的一般需求。以下是您或其他人可能会发现更有用的另一种转变......

更改所有元素命名空间的XSLT

以下XSLT会将所有元素的命名空间更改为stackoverflow.com

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

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

  <xsl:template match="*">
    <xsl:element name="{local-name()}" namespace="stackoverflow.com">
      <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

答案 1 :(得分:1)

很难理解你的问题中哪些是真实的,什么只是一个例子。从字面上看你的例子(如你自己的答案所做的那样),答案是:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="stackoverflow.com"
xmlns:e="example.com" 
exclude-result-prefixes="e">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/e:root">
    <newRoot>
        <xsl:apply-templates />
    </newRoot>
</xsl:template>

<xsl:template match="e:child">
    <child/>
</xsl:template>

</xsl:stylesheet>

更通用的答案是将所有元素从其现有名称空间移动到新名称空间:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="*">
    <xsl:element name="{local-name()}" namespace="stackoverflow.com">
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>