0

我想使用 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>

有必要避免它。我怎样才能只添加一个节点而不改变结构?另外,我希望像其他节点一样插入新节点。

4

2 回答 2

0

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

<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>

笔记:

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

如果命名空间未添加到此节点,它也会添加xmlns=""<PropertyGroup>(特别是对于给定模板的这种情况)

于 2019-02-15T08:47:25.433 回答
0

It's not clear what your expected output is.

If you want to keep the original namespace and insert the new element into it, then do:

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>

If you want to remove the namespace altogether, then do:

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>
于 2019-02-15T08:51:14.990 回答