4

我正在尝试对 XML 文档进行转换,但我找不到解决方案,因为我不知道 XSLT。我有 XML 文档:

<?xml version="1.0" encoding="UTF-8"?>
<addresses xmlns="http://www.test.org/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation='http://whatever/test.xsd'>

  <address>
    <name>Joe Tester</name>
    <street>Baker street 5</street>
  </address>

</addresses>

我想制作:

<?xml version="1.0" encoding="UTF-8"?>
<addresses xmlns="http://www.test.org/xml">

  <address>
    <name>Joe Tester</name>
    <street>Baker street 5</street>
  </address>

</addresses>

(考虑到 xsi:noNamespaceSchemaLocation="..." 在此之前已经排除了使用另一个 XSLT)。

有人可以帮我找到解决方案吗?

用于消除 xsi:noNamespaceSchemaLocation 的 XSLT 是:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>

<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="@xsi:noNamespaceSchemaLocation"/>

</xsl:stylesheet>
4

3 回答 3

4

我有两个选择:

XSLT1:

<?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="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="@*[local-name(.)='noNamespaceSchemaLocation']"/>
</xsl:stylesheet>

输出1:

<?xml version="1.0" encoding="utf-8"?>
<addresses xmlns="http://www.test.org/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <address>
    <name>Joe Tester</name>
    <street>Baker street 5</street>
  </address>
</addresses>

XSLT2:

<?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="*">
    <xsl:element name="{local-name(.)}">
      <xsl:apply-templates select="@* | node()"/>
    </xsl:element>
  </xsl:template>
  <xsl:template match="@*">
    <xsl:attribute name="{local-name(.)}">
      <xsl:value-of select="."/>
    </xsl:attribute>
  </xsl:template>

  <xsl:template match="@*[local-name(.)='noNamespaceSchemaLocation']"/>
</xsl:stylesheet>

输出2:

<?xml version="1.0" encoding="utf-8"?>
<addresses>
  <address>
    <name>Joe Tester</name>
    <street>Baker street 5</street>
  </address>
</addresses>
于 2013-01-07T08:29:00.040 回答
1

请试一试:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" exclude-result-prefixes="xsi"
>

  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:strip-space elements="*"/>

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

  <xsl:template match="*">
    <xsl:element name="{name()}" namespace="{namespace-uri()}">
      <xsl:copy-of select="namespace::*[not(. = 'http://www.w3.org/2001/XMLSchema-instance')]" />
      <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="@xsi:noNamespaceSchemaLocation"/>

</xsl:stylesheet>
于 2013-01-07T01:05:11.923 回答
0

您的问题是,在复制元素节点时<xsl:copy>,会隐式复制文档中该点范围内的命名空间节点。尝试为元素节点添加一个额外的模板以专门排除xsi命名空间:

<xsl:template match="*">
  <xsl:element name="{name()}" namespace="{namespace-uri()}">
    <xsl:copy-of select="namespace::*[not(name() = 'xsi')]" />
    <xsl:apply-templates select="@*|node()"/>
  </xsl:element>
</xsl:template>

如果您xsl:stylesheet有,xmlns:xsi那么您可能还会发现您需要按照此答案exclude-result-prefixes="xsi"中的建议添加。

这应该可以防止 xsi 命名空间出现在输出中,如果它只是因为它是从输入中复制而来的,尽管如果需要使输出格式正确(即,如果它需要输出一个元素或该命名空间中的属性)。

于 2013-01-07T09:12:11.573 回答