XSLT 1.0 多通道
XSLT 1.0 multi-passing
我有以下输入 xml:
<bookstores>
<store>
<name>Store 1</name>
<books>
<book>
<title>Book 1</title>
<author>Author 1</author>
<year>2000</year>
<price/>
</book>
<book>
<title>Book 2</title>
<author></author>
<year>2001</year>
<price/>
</book>
</books>
</store>
<store>
<name>Store 3</name>
<books>
<book>
<title>Book 1</title>
<year>2012</year>
<price/>
</book>
</books>
</store>
</bookstores>
我需要获取所有拥有已识别作者的书籍的商店,因此结果应该是:
<bookstores>
<store>
<name>Store 1</name>
<books>
<book>
<title>Book 1</title>
<author>Author 1</author>
<year>2000</year>
<price/>
</book>
</books>
</store>
</bookstores>
我尝试使用 exslt:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common">
<xsl:output method="xml" indent="yes" encoding="utf-8" />
<xsl:strip-space elements="*" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:variable name="firstPass">
<xsl:call-template name="processing" />
</xsl:variable>
<xsl:apply-templates select="exslt:node-set($firstPass)" />
</xsl:template>
<xsl:template name="processing" match="bookstores/store/books/book[author[string()='']]" />
<xsl:template match="bookstores/store/books/book[not(author)]" />
<xsl:template match="bookstores/store[not(books/book)]" />
</xsl:stylesheet>
- 过滤作者为空的图书
- 过滤没有作者标签的图书
- 过滤掉没有作者书籍的书目
但不幸的是,我不知道如何以正确的方式使用它。如何将 exslt 与多个匹配模板一起使用?
我觉得你可以一次搞定
<xsl:template match="store[not(books/book[author[normalize-space()]])]"/>
<xsl:template match="book[not(author[normalize-space()])]"/>
这样完整的代码是
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="store[not(books/book[author[normalize-space()]])]"/>
<xsl:template match="book[not(author[normalize-space()])]"/>
</xsl:stylesheet>
并在 https://xsltfiddle.liberty-development.net/3NzcBtk 处给出想要的输出。
你的方法可以简化为
<xsl:template match="store/books/book[string(author)='']" />
<xsl:template match="store[not(books/book/author)]" />
第一个在一个表达式中删除 book
没有 author
或空 author
的表达式。第二个删除 store
s,它有 book
s 而没有 author
或者根本没有 book
s,因为没有 book
就不能成为 author
.
我有以下输入 xml:
<bookstores>
<store>
<name>Store 1</name>
<books>
<book>
<title>Book 1</title>
<author>Author 1</author>
<year>2000</year>
<price/>
</book>
<book>
<title>Book 2</title>
<author></author>
<year>2001</year>
<price/>
</book>
</books>
</store>
<store>
<name>Store 3</name>
<books>
<book>
<title>Book 1</title>
<year>2012</year>
<price/>
</book>
</books>
</store>
</bookstores>
我需要获取所有拥有已识别作者的书籍的商店,因此结果应该是:
<bookstores>
<store>
<name>Store 1</name>
<books>
<book>
<title>Book 1</title>
<author>Author 1</author>
<year>2000</year>
<price/>
</book>
</books>
</store>
</bookstores>
我尝试使用 exslt:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common">
<xsl:output method="xml" indent="yes" encoding="utf-8" />
<xsl:strip-space elements="*" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:variable name="firstPass">
<xsl:call-template name="processing" />
</xsl:variable>
<xsl:apply-templates select="exslt:node-set($firstPass)" />
</xsl:template>
<xsl:template name="processing" match="bookstores/store/books/book[author[string()='']]" />
<xsl:template match="bookstores/store/books/book[not(author)]" />
<xsl:template match="bookstores/store[not(books/book)]" />
</xsl:stylesheet>
- 过滤作者为空的图书
- 过滤没有作者标签的图书
- 过滤掉没有作者书籍的书目
但不幸的是,我不知道如何以正确的方式使用它。如何将 exslt 与多个匹配模板一起使用?
我觉得你可以一次搞定
<xsl:template match="store[not(books/book[author[normalize-space()]])]"/>
<xsl:template match="book[not(author[normalize-space()])]"/>
这样完整的代码是
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="store[not(books/book[author[normalize-space()]])]"/>
<xsl:template match="book[not(author[normalize-space()])]"/>
</xsl:stylesheet>
并在 https://xsltfiddle.liberty-development.net/3NzcBtk 处给出想要的输出。
你的方法可以简化为
<xsl:template match="store/books/book[string(author)='']" />
<xsl:template match="store[not(books/book/author)]" />
第一个在一个表达式中删除 book
没有 author
或空 author
的表达式。第二个删除 store
s,它有 book
s 而没有 author
或者根本没有 book
s,因为没有 book
就不能成为 author
.