SoaAlex
SoaAlex

Reputation: 512

How to check if value exists in an array from another file with xlst

I have an array in a .txt like this:

Value1
Value2
Value3...

I have an xml file that has some tags containing these values like this:

<catalog>
    <object>
        <id> Value1 </id>
        <title> title 1 </title>
        <name> name1 </name>
    </object>
    <object>
        <id> Undesired value </id>
        <title> title 2 </title>
        <name> name2 </name>
    </object>
<catalog>

I want to export for example titles of this xml ONLY if their ID exists in the array of my .txt file.

Is this possible using XSLT ?

The output would be something like that:

<output>
    <object>
        <id> Value1 </id>
        <title> title 1 </title>
        <name> name 1 </name>
    </object>
...
</output>

Upvotes: 0

Views: 331

Answers (2)

Thomas Hansen
Thomas Hansen

Reputation: 777

Please consider the following awk solution an alternative (since I simply can't think of any using XSLT).

$ cat tst.awk
BEGIN { print "<output>" }
NR==FNR {
  values[$0]
  next
}

/<object>/ {
  f=1
}
f { 
  i=i $0 ORS
}
/<\/object>/ {
  for (value in values)
  if(i ~ value){
    printf "%s", i
  } 
  i=f=""
}
END { print "</output>"}

Save the script as tst.awk, your list as values.txt, and, finally, the XML file as input.xml, and then run it like so:

$ awk -f tst.awk values.txt input.xml

It's tested with GNU Awk 5.1.0, but will work on any Unix box. If interested, I'm happy to add an explanation of the code.

Upvotes: 1

Pierre Fran&#231;ois
Pierre Fran&#231;ois

Reputation: 6063

In the case you are using XSLT 1.0, and the processor you use is called from the command line like xsltproc, you can pass the content of a text file to XSLT as a string variable.

In the example below, I will pass the content of the text file to the variable $list invoking xsltproc as follows:

xsltproc --stringparam list "$(cat file.txt)" transform.xsl input.xml

or (better):

xsltproc --stringparam list "$(<file.txt)" transform.xsl input.xml

The correspondig stylesheet transform.xsl is:

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="xml" indent="yes" encoding="utf-8" />

  <xsl:template match="catalog">
    <output>
      <xsl:for-each select="object[contains($list, normalize-space (id))]">
        <xsl:copy-of select="." />
      </xsl:for-each>
    </output>
  </xsl:template>

</xsl:stylesheet>

Upvotes: 0

Related Questions