我有以下XML:
<?xml version="1.0"?>
<Transaction>
<Product>
<ProductRq>
<ContactInfo>
<!-- several child elements -->
</ContactInfo>
<OrderInfo>
<!-- several child elements -->
</OrderInfo>
<ProductInfo>
<!-- several child elements -->
</ProductInfo>
<AddressInfo>
<!-- several child elements -->
</AddressInfo>
<AuditInfo>
<!-- several child elements -->
</AuditInfo>
<DeliveryInfo>
<!-- several child elements -->
</DeliveryInfo>
</ProductRq>
</Product>
</Transaction>
为了简洁起见,我在<ProductRq>
标记中遗漏了几个孩子,其中包含4或5个类似于<OrderInfo>
和<CustomerInfo>
的子元素,以及* Info元素的子节点。
我需要在保留* Info标记的同时删除Order和<CustomerInfo>
等元素的子元素。在7个标签中,大约4个标签将通过此过程。我想不出怎么做而不重复:
<xsl:template match="Transcation/Product/ProductRq/<tag name here>/*" />
为<ProductRq>
的每个孩子。有没有办法利用上下文节点(<ProductRq>
)并循环遍历子节点,除了上面的内容之外删除自己的子节点?
编辑:
我添加了<ProductRq>
的剩余子标记。除<AuditInfo>
和<ContactInfo>
之外的所有代码都必须删除其子节点。
答案 0 :(得分:1)
一种解决方案是应用以下XSLT:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<!-- identity transform -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<!-- skip all child nodes of ProductRq except they are AuditInfo or ContactInfo -->
<xsl:template match="ProductRq/*[not(self::AuditInfo | self::ContactInfo)]">
<xsl:element name="{name(.)}" /> <!-- so create an element with this name -->
</xsl:template>
</xsl:stylesheet>
<强>输出:强>
<?xml version="1.0"?>
<Transaction>
<Product>
<ProductRq>
<ContactInfo>
<!-- several child elements -->
</ContactInfo>
<OrderInfo/>
<ProductInfo/>
<AddressInfo/>
<AuditInfo>
<!-- several child elements -->
</AuditInfo>
<DeliveryInfo/>
</ProductRq>
</Product>
</Transaction>
答案 1 :(得分:0)
我需要移除
Order
和<CustomerInfo>
等元素的子元素<!-- XSLT 2.0 and up --> <xsl:template match="ProductRq/*[ends-with(name(), 'Info')]/*" /> <!-- XSLT 1.0 variant, as ends-with() does not exist here --> <xsl:template match="ProductRq/*[ substring-before(name(), 'Info') != '' and substring-after(name(), 'Info') = '' ]/*" />
同时保留* Info标记。
您要找的模板是
to_csv
答案 2 :(得分:0)
撰写与ProductRq
匹配的模板:
<xsl:template match="ProductRq">
<xsl:copy>
<xsl:apply-templates select="ContactInfo | OrderInfo | ProductInfo | AddressInfo"/>
</xsl:copy>
</xsl:template>
如您所见,select
子句包含要包含的所有子节点。
默认情况下,它执行深层复制(带子节点)。
但您写道,某些节点(例如ContactInfo
和OrderInfo
)只能在浅层模式下复制。
(我假设这种模式应该只涉及复制子文本节点
但仅此而已。复制&#34;空&#34;标签似乎是一个奇怪的概念。)
为了只拥有这些节点的浅层副本,请写另一个tempate:
<xsl:template match="ContactInfo | OrderInfo">
<xsl:copy><xsl:apply-templates select="text()"/></xsl:copy>
</xsl:template>
总而言之,您在2个地方写下所涉及的节点名称(用&#34; |&#34;分隔):
无论如何你必须写这些名字。