XSLT需要非常简单的转换

时间:2012-02-22 13:31:17

标签: xml xslt

我需要在xml文件上运行转换。它将是非常基本的,但在我有点迷失之前从未做过任何xslt工作。我有很多SO Q& A's但是还没有能够解决这个问题?

我需要的是我的xml文件有一个模式引用,我需要将它更改为另一个模式引用。

<?xml version="1.0" encoding="UTF-8"?>
<Schedule xmlns="http://www.xxx.com/12022012/schedule/v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.xxx.com/12022012/schedule/v2 ../Schema/Schema_v2.xsd">
  <Interface_Header>
  </Interface_Header>
...
</Schedule>

我只是想将V2更改为V3,并保持文件的其余部分完好无损?这听起来很简单,但我似乎无法弄清楚这一点?我在这里尝试了一个简单的xslt: -

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

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

但是使用它输出我的所有值而没有任何xml标记。

谢谢你。

2 个答案:

答案 0 :(得分:0)

使用:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xmlns:ns="new_namespace">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="@xsi:schemaLocation">
        <xsl:attribute name="xsi:schemaLocation">
            <xsl:text>new_schema_location</xsl:text>
        </xsl:attribute>
    </xsl:template>

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

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

</xsl:stylesheet>

应用于提供的XML生成

<Schedule xsi:schemaLocation="new_schema_location" xmlns="ns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Interface_Header>
    </Interface_Header>
    ...
</Schedule>

答案 1 :(得分:0)

当您不需要新的模式位置来拥有xsi名称空间时,以下内容将起作用:

<xsl:output indent="yes" method="xml"/>

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

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

<xsl:template match="@*[local-name() = 'schemaLocation']">
    <xsl:attribute name="schemaLocation">newSchemaLocation</xsl:attribute>
</xsl:template>

当你确实需要再次使用xsi命名空间时,当然需要在模板中提及它,因此必须在样式表标题中声明,如下所示,其中作为演示也是local-name()函数被name()函数替换;前者包括名称空间,后者不包括:

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

...

    <xsl:template match="@*[name() = 'xsi:schemaLocation']">
        <xsl:attribute name="xsi:schemaLocation">newSchemaLocation</xsl:attribute>
    </xsl:template>

</xsl:stylesheet>

请注意,两个解决方案都依赖于特定的模板路径(@*[local-name()=...]),而不是特定的模板路径(@*)。