我有一个复杂的XML,这里给出了简化版本。 我想要实现的是仅从给定的节点集获取数据(文本或属性值) 在XML中。许多示例仅适用于XPATH。但我的XML结构很复杂,我想使用递归方法扫描节点而不是硬编码XPATH。
INPUT:
<Root>
<Book>
<Content >
<Chapter id="1" startpage="1" endpage="20">
<Topic id="1">
<Title>Title1</Title>
<Content>Paragraphs</Content>
</Topic>
<Topic id="1.1">
<Title>Title1.1</Title>
<Content>Paragraphs</Content>
</Topic>
<Topic id="1.2">
<Title>Title1.2</Title>
<Content>Paragraphs</Content>
</Topic>
</Chapter>
<Chapter id="2" startpage="21" endpage="90">
<Topic id="2">
<Title>Title2</Title>
<Content>Paragraphs</Content>
</Topic>
<Topic id="2.1">
<Title>Title2.1</Title>
<Content>Paragraphs</Content>
</Topic>
<Topic id="2.1.2">
<Title>Title2.1.2</Title>
<Content>Paragraphs</Content>
</Topic>
</Chapter>
<Index>
Some more nodes here
</Index>
</Content>
</Book>
</Root>
期望的输出:
<Root>
<Book>
<Content>
<Chapter id="1" startpage="1" endpage="20">
<Title>Title1</Title>
<Title>Title1.1</Title>
<Title>Title1.2</Title>
</Chapter>
<Chapter id="2" startpage="21" endpage="90">
<Title>Title2</Title>
<Title>Title2.1</Title>
<Title>Title2.1.2</Title>
</Chapter>
</Book>
</Root>
CURRENT XSL:
<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>Root</name>
<name>Book</name>
<name>Chapter</name>
<name>Title</name>
</ns:WhiteList>
<xsl:variable name="whistList" select="document('')/*/ns:WhiteList" />
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*">
<xsl:if test="attribute::*[name()=$whistList/*]">
<xsl:copy/>
</xsl:if>
</xsl:template>
<xsl:template match="*">
<xsl:if test="descendant-or-self::*[name()=$whistList/*]">
<xsl:copy>
<xsl:value-of select="node()" />
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:1)
我已将以下内容添加到您的样式表中:
<xsl:template match="Topic">
<xsl:apply-templates/>
</xsl:template>
,输出现在是
<Root>
<Book>
<Content>
<Chapter>
<id>1</id>
<startpage>1</startpage>
<endpage>20</endpage>
<Title>Title1</Title>
<Title>Title1.1</Title>
<Title>Title1.2</Title>
</Chapter>
<Chapter>
<id>2</id>
<startpage>21</startpage>
<endpage>90</endpage>
<Title>Title2</Title>
<Title>Title2.1</Title>
<Title>Title2.1.2</Title>
</Chapter>
</Content>
</Book>
</Root>
答案 1 :(得分:0)
看起来这个工作正常。但是,它仍然显示我不想要的节点。我相信这是因为节点中有一个属性。
<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>
<elename>Chapter</elename>
<elename>Title</elename>
</ns:WhiteList>
<xsl:variable name="whistList" select="document('')/*/ns:WhiteList" />
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*">
<xsl:copy>
<xsl:call-template name="flatattr"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*" name="flatattr">
<xsl:element name="{local-name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
<xsl:template match="*">
<xsl:if test="descendant-or-self::*[name()=$whistList/*]">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
<xsl:template match="Expression[ancestor::Expression]">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="SimpleExpression">
<xsl:text>(</xsl:text>
<xsl:apply-templates />
<xsl:text>)</xsl:text>
</xsl:template>
<xsl:template match="ValueExpression|Operator">
<xsl:text>(</xsl:text>
<xsl:value-of select="." />
<xsl:text>)</xsl:text>
</xsl:template>
</xsl:stylesheet>
答案 2 :(得分:0)
如果仅决定因素是节点的名称(无论节点的路径如何),您可以尝试:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="whiteList">
<name>Root</name>
<name>Book</name>
<name>Chapter</name>
<name>Title</name>
<name>id</name>
</xsl:variable>
<xsl:variable name="whiteListSet" select="exsl:node-set($whiteList)/name" />
<xsl:template match="*">
<xsl:choose>
<xsl:when test="name()=$whiteListSet">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="@*|node()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="@*">
<xsl:if test="name()=$whiteListSet and name(parent::*)=$whiteListSet">
<xsl:copy/>
</xsl:if>
</xsl:template>
<xsl:template match="text()">
<xsl:if test="name(parent::*)=$whiteListSet">
<xsl:copy/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
当上述内容应用于您的示例输入时,结果为:
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<Book>
<Chapter id="1">
<Title>Title1</Title>
<Title>Title1.1</Title>
<Title>Title1.2</Title>
</Chapter>
<Chapter id="2">
<Title>Title2</Title>
<Title>Title2.1</Title>
<Title>Title2.1.2</Title>
</Chapter>
</Book>
</Root>