Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 如果数组中匹配,则运行XSL转换,如果不匹配,如何放弃?_Xml_Bash_Xslt - Fatal编程技术网

Xml 如果数组中匹配,则运行XSL转换,如果不匹配,如何放弃?

Xml 如果数组中匹配,则运行XSL转换,如果不匹配,如何放弃?,xml,bash,xslt,Xml,Bash,Xslt,我想根据文章编号将某些文章导入数据库。允许的物品编号位于“allowedArticles”变量中。如果允许进口该物品,则该物品的所有物品都应进口。(文章列表会更大,下面的例子就是一个例子。) 应该以某种方式丢弃与列表中的某个项目不匹配的项目 此XSLT将在多个文件上运行,因为导出时每个文件中都有一个项目,尽管这可能是一个大文件中的所有项目。用一个大文件做我想做的事情会更容易吗 XSLT是否可以做到这一点?如果可以,最好的解决方案是什么?我是否应该着手编写一个能够支持此操作的bash脚本 你需要更

我想根据文章编号将某些文章导入数据库。允许的物品编号位于“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>

86369815636833367772
应该以某种方式丢弃与我的列表中的某个项目不匹配的项目

因此,如果我理解正确,您只需删除“不允许”的元素即可:

<?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>

86369815636833367772
标识模板将复制所有内容,空模板将匹配您不允许的文章并丢弃它们

编辑:

正如@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"/>


此XSLT将在多个文件上运行,因为导出时每个文件中都有一个项目,尽管这可能是一个大文件中的所有项目。用一个大文件做我想做的事情会更容易吗


我认为这是一个偏好和/或性能的问题,取决于您的输入文件和特定场景。一般来说,我更喜欢一个转换,而不是很多较小的转换,但是文件越大,进行多次转换可能会更好。

FYI:
content[not(@exported dbid=$allowedArticles/Item)]
匹配甚至没有
@exported dbid
属性的元素。这可能是也可能不是所希望的。此外,您还可以使用更易于管理的
。是的,我知道这一点,但是,每当您使用像这里这样的包含式选择时,我认为列表中没有Id的任何内容都应该被丢弃。不过,你对这个序列的看法是正确的,我会在我的回答中加上这一点。无论如何,这更像是给OP的参考资料。:)谢谢你们两位@TobiasKlevenz您在编辑中编写了xsl:variable而不是xsl:sequence。他们平等吗?我会尽快测试你的建议,然后可能会接受你的答案。允许的文章也可以从一个文件中提取,比如说,每个文章编号都在一行吗?