我想根据文章编号将某些文章导入数据库。允许的文章编号位于“allowedArticles”变量中。如果允许导入文章,则应导入该文章的所有内容。 (文章列表会更大,下面的例子只是一个例子。)
与我列表中的某篇文章不匹配的文章应该以某种方式丢弃。
此XSLT将在多个文件上运行,因为导出是使用每个文件中的一个项目进行的,尽管这可能是一个大文件中的所有项目。用一个大文件做我想要的更容易吗?
这是否可以使用XSLT,如果是这样,最好的解决方案是什么?我是否应该编写一个可以支持此操作的bash脚本?
您还需要更多信息吗?
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xpath-default-namespace="http://xmlns.escenic.com/2009/import">
<xsl:output omit-xml-declaration="no" indent="yes"/>
<!-- Array of articles to include in the import, optimize by loading from external file -->
<xsl:variable name="allowedArticles" as="element()*">
<Item>86369</Item><Item>81563</Item><Item>68333</Item><Item>67772</Item>
</xsl:variable>
<!-- If the article ID is NOT in allowedArticles do nothing with them -->
<xsl:template match="/escenic/content">
<xsl:variable name="exportedDbId" select="@exported-dbid" />
<xsl:for-each select="$allowedArticles">
<xsl:choose>
<xsl:when test="$exportedDbId=.">
<!-- Identity template : copy all text nodes, elements and attributes -->
<!-- It does not work to copy all nodes from here, as it's the wrong context or something like that. -->
</xsl:when>
<xsl:otherwise />
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:2)
与我列表中某篇文章不匹配的文章应该以某种方式丢弃。
所以如果我坚持并且你想要做的就是删除那些不允许的元素&#34;你可以这样做:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xpath-default-namespace="http://xmlns.escenic.com/2009/import">
<xsl:output omit-xml-declaration="no" indent="yes"/>
<!-- identity template -->
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:variable name="allowedArticles" as="element()*">
<Item>86369</Item><Item>81563</Item><Item>68333</Item><Item>67772</Item>
</xsl:variable>
<!-- empty template to discard content elements that are not in allowedArticles -->
<xsl:template match="content[not(@exported-dbid=$allowedArticles/Item)]"/>
</xsl:stylesheet>
身份模板将复制所有内容,空模板将与您不允许的文章匹配并丢弃它们。
修改强>
正如@tomalak所说,序列将是一种更优雅的方式来处理您的允许ID:
<xsl:variable name="AllowedItems" select="(86369, 81563, 68333, 67772)"/>
要回答评论中的问题,这等于:
<xsl:variable name="AllowedItems">
<xsl:sequence select="(86369, 81563, 68333, 67772)"/>
</xsl:variable>
如果你想从外部文件中引用AllowedItems,让我们假设你有一个名为AllowedItems.xml的文件,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<AllowedItems>
<Item>86369</Item>
<Item>81563</Item>
<Item>68333</Item>
<Item>67772</Item>
</AllowedItems>
然后你定义你的变量:
<xsl:variable name="AllowedItems"
select="document('AllowedItems.xml')/AllowedItems/Item"/>
这里的document()
函数要求AllowedItems.xml与xslt位于同一目录中,你也可以在这里使用相对路径或完整的Uri,你可以阅读文档here
此XSLT将在多个文件上运行,因为导出是在每个文件中使用一个项目进行的,尽管这可能是一个大文件中的所有项目。用一个大文件做我想要的更容易吗?
我认为这是偏好和/或性能问题,取决于您的输入文件和您的具体方案。我通常更喜欢对很多较小的转换进行一次转换,但是文件越大,你可能会有更多的转换。