在 运行 XSL 处理器处理 XML 文件时保留 xmlns 位置

Keep xmlns location while running XSL processor on XML file

我想使用 xslt 将节点添加到 XML 文档。我正在使用 msxsl 作为处理器。 XML 文档具有以下结构:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <PlatformShortName>SDK_NAME</PlatformShortName>
    </PropertyGroup>
</Project>

XSL 规则插入所需的节点:

(编辑: 添加了 XSL 命名空间)

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ms="http://schemas.microsoft.com/developer/msbuild/2003"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
exclude-result-prefixes="ms">
<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="yes" />

<xsl:template match="ms:Project/ms:PropertyGroup">
    <PropertyGroup>
        <xsl:element name="PlatformInstructionSet">AMRv7</xsl:element>
        <xsl:apply-templates/>
    </PropertyGroup>
</xsl:template>

<xsl:template match="*">
    <xsl:element name="{name()}">
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

但结果已将命名空间属性从 Project 移动到 PropertyGroup

(编辑:我希望 ProjectPropertyGroup 与输入相同。)

<Project>
    <PropertyGroup xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PlatformInstructionSet>AMRv7</PlatformInstructionSet>
        <PlatformShortName>SDK_NAME</PlatformShortName>
    </PropertyGroup>
</Project>

避而远之。如何在不更改结构的情况下只添加一个节点?此外,我希望像其他节点一样插入新节点。

根据您提供的输入,模板可以重写如下:

<xsl:template match="ms:Project/ms:PropertyGroup">
    <PropertyGroup xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
        <xsl:element name="PlatformInstructionSet">AMRv7</xsl:element>
        <xsl:apply-templates />
    </PropertyGroup>
</xsl:template>

<xsl:template match="*">
  <xsl:element name="{local-name()}" namespace="http://schemas.microsoft.com/developer/msbuild/2003">
    <xsl:apply-templates select="node() | @*"/>
  </xsl:element>
</xsl:template>

注:

<PropertyGroup> 中添加 xmlns="http://schemas.microsoft.com/developer/msbuild/2003" 会认为它的子节点与父节点位于同一命名空间中,因此不会将其添加到子节点中。

如果命名空间没有添加到此节点,它还会在 <PropertyGroup> 中添加 xmlns=""。 (特别针对给定模板的这种情况)

不清楚您的预期输出是什么。

如果你想保留原来的命名空间并将新元素插入其中,那么做:

XSLT

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ms="http://schemas.microsoft.com/developer/msbuild/2003"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
exclude-result-prefixes="ms">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="ms:PropertyGroup">
    <xsl:copy>
        <PlatformInstructionSet>AMRv7</PlatformInstructionSet>
        <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

如果您想完全删除命名空间,请执行以下操作:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ms="http://schemas.microsoft.com/developer/msbuild/2003"
exclude-result-prefixes="ms">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="*">
    <xsl:element name="{local-name()}">
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>

<xsl:template match="ms:PropertyGroup">
    <PropertyGroup>
        <PlatformInstructionSet>AMRv7</PlatformInstructionSet>
        <xsl:apply-templates/>
    </PropertyGroup>
</xsl:template>

</xsl:stylesheet>