xml - 如何使用具有依赖关系的 xslt 排除 xml 对象
问题描述
我有以下输入xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<technicalAssets>
<composedId>
<id>A1</id>
</composedId>
<technicalName>TestA1</technicalName>
<prerequisites>
<technicalAssetPrerequisites>
<technicalAssetIds>
<composedId>
<id>B1</id>
</composedId>
</technicalAssetIds>
</technicalAssetPrerequisites>
</prerequisites>
</technicalAssets>
<technicalAssets>
<composedId>
<id>A2</id>
</composedId>
<technicalName>TestA2</technicalName>
</technicalAssets>
<technicalAssets>
<composedId>
<id>B1</id>
</composedId>
<technicalName>TestB1</technicalName>
</technicalAssets>
<products>
<entitlementRules>
<technicalAssetId>
<composedId>
<id>A1</id>
</composedId>
</technicalAssetId>
</entitlementRules>
</products>
</root>
我想应用一个 XSLT 转换,它只列出产品technicalAssets
中引用的或产品引用的那些。
我怎样才能做到这一点?预期输出:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<technicalAssets>
<composedId>
<id>A1</id>
</composedId>
<technicalName>TestA1</technicalName>
<prerequisites>
<technicalAssetPrerequisites>
<technicalAssetIds>
<composedId>
<id>B1</id>
</composedId>
</technicalAssetIds>
</technicalAssetPrerequisites>
</prerequisites>
</technicalAssets>
<technicalAssets>
<composedId>
<id>B1</id>
</composedId>
<technicalName>TestB1</technicalName>
</technicalAssets>
<products>
<entitlementRules>
<technicalAssetId>
<composedId>
<id>A1</id>
</composedId>
</technicalAssetId>
</entitlementRules>
</products>
</root>
我目前正在使用以下 xslt,但它复制了出现 TechnicalAssetId 的产品节点内的节点 TechnicalAssets。那不是我需要的。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<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="technicalAssets"/>
<xsl:template match="technicalAssetId">
<xsl:copy>
<xsl:apply-templates/>
<xsl:for-each select="/root/technicalAssets[composedId/id/text() = current()/composedId/id/text()]">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
解决方案
您可以使用 anxsl:key
来选择所有composedId/id
不是technicalAssets
.
然后,您可以key()
在模板中使用匹配的谓词technicalAssets
来检查是否没有匹配的键composedId/id
。
因此,与其尝试复制您想要保留的内容,不如删除您不想保留的内容。
例子...
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="ids" match="*[not(self::technicalAssets)]/composedId/id" use="."/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="technicalAssets[not(key('ids',composedId/id))]"/>
</xsl:stylesheet>
推荐阅读
- email - 电子邮件回复不起作用
- google-tag-manager - 仅当 div-x 存在时才定义槽
- python - 使用 subprocess.run() 和共享输入在 Python 中替换 Bash 进程
- javascript - 数一数注册了多少用户?
- pointers - 尝试读取和写入 proc 时从不兼容的指针类型 [-Werror=incompatible-pointer-types] 初始化错误
- c# - 棱镜事件在发布模式下不起作用
- reactjs - Mobx 状态树嵌套存储注入
- java - 如何在不创建 POJO 的情况下映射标签的值?
- mongoid - 如何将 rails_admin 与 mongoid 一起使用?
- java - 为什么 Apache Velocity 不能处理多个点键