对这些问题的基本性质表示道歉 - 我对XSLT(以及Stack Overflow)也是全新的.
我需要转换Sharepoint Web服务返回的以下XML:
<GetGroupCollectionFromUser xmlns=
"http://schemas.microsoft.com/sharepoint/soap/directory/">
<Groups>
<Group ID="3" Name="Group1" Description="Description" OwnerID="1"
OwnerIsUser="False" />
<Group ID="15" Name="Group2" Description="Description"
OwnerID="12" OwnerIsUser="True" />
<Group ID="16" Name="Group3" Description="Description"
OwnerID="7" OwnerIsUser="False" />
</Groups>
</GetGroupCollectionFromUser>
Run Code Online (Sandbox Code Playgroud)
进入这个:
<GetGroupCollectionFromUser xmlns=
"http://schemas.microsoft.com/sharepoint/soap/directory/">
<Groups>
<Group Name="Group1" />
<Group Name="Group2" />
<Group Name="Group3" />
</Groups>
</GetGroupCollectionFromUser>
Run Code Online (Sandbox Code Playgroud)
基本上,我需要删除除Name之外的每个Group元素的所有属性.经过大量的研究和修补,特别是从原始XML中删除命名空间声明后,我想出了一些让我几乎完全符合我需要的东西:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="no"/>
<xsl:template match="/GetGroupCollectionFromUser">
<xsl:copy>
<xsl:apply-templates select="Groups" />
</xsl:copy>
</xsl:template>
<xsl:template match="Groups">
<xsl:copy>
<xsl:apply-templates select="Group" />
</xsl:copy>
</xsl:template>
<xsl:template match="Group">
<xsl:copy>
<xsl:apply-templates select="@Name" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
但是,上面给出了作为文本插入到Group元素中的Name属性的值,而不是Name属性,如下所示:
<GetGroupCollectionFromUser>
<Groups>
<Group>Group1</Group>
<Group>Group2</Group>
<Group>Group3</Group>
</Groups>
</GetGroupCollectionFromUser>
Run Code Online (Sandbox Code Playgroud)
这最终将由期望以属性为中心的XML的第三方应用程序使用.我确定我错过了一些令人尴尬的东西,但无论我用它做什么,我似乎都无法仅仅引入Name属性.两个问题:
如何更改XSLT以返回每个Group元素的Name属性,而不是其值作为文本?
而且,我如何正确处理命名空间?当我将它包含在XSLT中时,尝试基于我在这里和网上其他地方找到的示例的几种方法,我什么也得不到.
提前感谢任何建议.
这可能是正确产生所需结果的最短转换之一:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<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="@*[not(name()='Name')]"/>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
当应用于提供的 XML 文档时:
<GetGroupCollectionFromUser xmlns=
"http://schemas.microsoft.com/sharepoint/soap/directory/">
<Groups>
<Group ID="3" Name="Group1" Description="Description" OwnerID="1" OwnerIsUser="False" />
<Group ID="15" Name="Group2" Description="Description" OwnerID="12" OwnerIsUser="True" />
<Group ID="16" Name="Group3" Description="Description" OwnerID="7" OwnerIsUser="False" />
</Groups>
</GetGroupCollectionFromUser>
Run Code Online (Sandbox Code Playgroud)
产生了想要的正确结果:
<GetGroupCollectionFromUser xmlns="http://schemas.microsoft.com/sharepoint/soap/directory/">
<Groups>
<Group Name="Group1"/>
<Group Name="Group2"/>
<Group Name="Group3"/>
</Groups>
</GetGroupCollectionFromUser>
Run Code Online (Sandbox Code Playgroud)
解释:
身份规则(模板)“按原样”复制每个节点。
只有一个模板可以覆盖身份规则。它匹配名称不是“Name”的任何属性。模板的主体为空,这会导致任何匹配的属性都不会被复制。
使用和覆盖身份规则是最基本、最强大的 XSLT 设计模式。在这里阅读相关内容。