[英]xslt - How to filter a XML document using xslt, keep given elements, discard all others
我有這個xml:
<?xml version="1.0" encoding="utf-8"?>
<xml>
<head>
<name>This is my XML</name>
<version>This is my XML</version>
</head>
<body>
<item id="SH2-99435">
<properties>
<property id="69">
<name>This is a property</name>
<amount>54.13</amount>
<estructure id="IZ4">
<name>caterpillar</name>
<location><zipCode>02210</zipCode><street>South Station</street></location>
</estructure>
</property>
<features id="ABC3">
<feature>If it works, a bug is another feature.</feature>
<feature>feature!!</feature>
</features>
</properties>
<coding>
<codename>Silent Hill 2</codename>
<developer>Team Silent</developer>
<publisher>Konami</publisher>
</coding>
</item>
<item id="SH3-4498">
<text value="it has values like the other item"/>
</item>
<item id="MGS-2">
<text value="it has values like the other item"/>
</item>
</body>
</xml>
我想實現這個目標:
<?xml version="1.0" encoding="utf-8"?>
<xml>
<head>
<name>This is my XML</name>
<version>This is my XML</version>
</head>
<body>
<item>
<properties>
<property id="69">
<amount>54.13</amount>
<estructure id="IZ4">
<name>caterpillar</name>
<location><zipCode>02210</zipCode><street>South Station</street></location>
</estructure>
</property>
</properties>
</item>
<item id="SH3-4498">
<text value="it should have properties and the selected sons"/>
</item>
<item id="MGS-2" >
<text value="it should have properties and the selected sons"/>
</item>
</body>
</xml>
我有這樣的東西,它正確過濾:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="xml/body/item/coding" />
<xsl:template match="xml/body/item/properties/features" />
<xsl:template match="xml/body/item/properties/property/name" />
</xsl:stylesheet>
我被告知通過運行此過濾器將生成10個文件,每個文件都有不同的標簽; 但是如果出現新標簽,我們將不得不更改10個文件以排除不需要的標簽,而不是僅在需要的文件上添加標簽。 例如,在另一個文件中,僅包括編碼,依此類推。
我試過這個:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="some:ns">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:strip-space elements="*" />
<ns:WhiteList>
<name>amount</name>
<name>estructure</name>
</ns:WhiteList>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template
match="*[not(descendant-or-self::*[name()=document('')/*/ns:WhiteList/*])]" />
</xsl:stylesheet>
但它並沒有復制estructure的孩子們。 你知道我能做什么嗎?
謝謝。
更新。 添加理由以這種方式而不是相反的方式,以及更具描述性的問題。
我不接受這個答案,但是在回答你的直接問題時,你正在測試作為estructure元素的祖先(或自我)的元素,但你忽略了其他任何東西。 這意味着忽略了estructure的后代。 將xsl:if條件更改為以下內容
<xsl:if
test="descendant-or-self::*[generate-id(.)=$copyValue2]|ancestor::*[generate-id(.)=$copyValue2]">
呸。
老實說,你的第一個XSLT更好,更清潔。
如果你准確地解釋了你試圖遵循轉換的規則,那可能會有所幫助。 如果規則要復制除某些節點之外的所有內容,那么您的第一個XSLT就是理想的選擇。 如果規則只復制顯式節點,那么你能否提供一些關於究竟需要復制的更多細節,並且應該可以更好地挖掘更好的東西。
編輯:
回應澄清,試試這個XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="some:ns">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<ns:WhiteList>
<name>amount</name>
<name>estructure</name>
</ns:WhiteList>
<xsl:variable name="whistList" select="document('')/*/ns:WhiteList" />
<xsl:template match="@*">
<xsl:copy/>
</xsl:template>
<xsl:template match="*">
<xsl:if test="descendant-or-self::*[name()=$whistList/*]|ancestor::*[name()=$whistList/*]">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
我試圖通過使用變量來保持文檔查找來整理它。 注意使用xsl的原因:if是你不能在模板匹配中使用變量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.