All Projects → bdukes → grunt-xmlpoke

bdukes / grunt-xmlpoke

Licence: MIT license
Updates values in XML files based on XPath queries. Similar to the `xmlpoke` task in NAnt.

Programming Languages

javascript
184084 projects - #8 most used programming language

Labels

Projects that are alternatives of or similar to grunt-xmlpoke

grunt-pug-sass-skeleton
boilerplate project of pug and sass using grunt
Stars: ✭ 14 (+7.69%)
Mutual labels:  grunt
grunt-mocha-cli
Run Mocha server-side tests in Grunt.
Stars: ✭ 42 (+223.08%)
Mutual labels:  grunt
viaduct
CMS for via. Moved to https://gitlab.com/studieverenigingvia/viaduct
Stars: ✭ 16 (+23.08%)
Mutual labels:  grunt
Kotsu
✨ Clean, opinionated foundation for new projects — to boldly go where no man has gone before
Stars: ✭ 48 (+269.23%)
Mutual labels:  grunt
jscrambler
Monorepo of Jscrambler's Javascript Client and Integrations
Stars: ✭ 118 (+807.69%)
Mutual labels:  grunt
TemplateEngine
Design and build web applications with components using only your web browser
Stars: ✭ 41 (+215.38%)
Mutual labels:  grunt
TypeScript-Boilerplate
A TypeScript Grunt Boilerplate
Stars: ✭ 13 (+0%)
Mutual labels:  grunt
generator-veams
Scaffold modern frontend web apps or web pages with a static site generator (Assemble or Mangony), Grunt and/or Gulp, Sass and Bower. Use modern frameworks like Bourbon, Bootstrap or Foundation and structure your JavaScript with ES Harmony support.
Stars: ✭ 45 (+246.15%)
Mutual labels:  grunt
browser-extension
Hunter for Chrome and Firefox
Stars: ✭ 15 (+15.38%)
Mutual labels:  grunt
antares-front-end
💻 Anatres Project Front-end Implementation. Create projects with clean material-design layouts, to improve user experience with fully responsive and elastic system. Object orientend javascript with Vue components, easy to use css grids, forms, widgets, build system based on Webpack and Grunt, and many more.
Stars: ✭ 35 (+169.23%)
Mutual labels:  grunt
castlecss-boilerplate
A simple and mobile-friendly HTML5 template with CastleCSS to kickstart your website
Stars: ✭ 29 (+123.08%)
Mutual labels:  grunt
gruntworkflows
Repository for my tutorial course: Grunt.js Web Workflows on LinkedIn Learning and Lynda.com.
Stars: ✭ 28 (+115.38%)
Mutual labels:  grunt
generator-sf
Yeoman generator that scaffolds out a Symfony PHP app including Browsersync, various CSS preprocessors, jspm, webpack, browserify and Service Worker
Stars: ✭ 14 (+7.69%)
Mutual labels:  grunt
Exceptionless.UI
Exceptionless web user interface
Stars: ✭ 105 (+707.69%)
Mutual labels:  grunt
Bolt
⚡ is a fast grunt based, data driven, static site seed project, for rapid web development of PWA's or JAMstack projects
Stars: ✭ 30 (+130.77%)
Mutual labels:  grunt
flag-icons
A beautiful svg + png + sass + css collection of 261 flags.
Stars: ✭ 61 (+369.23%)
Mutual labels:  grunt
rdm-app
Code for the rdm.openlighting.org site
Stars: ✭ 17 (+30.77%)
Mutual labels:  grunt
grunt-assemble-i18n
Assemble middleware for adding i18n support to projects.
Stars: ✭ 25 (+92.31%)
Mutual labels:  grunt
docker-npm
npm, yarn, node, npx, bower, grunt, gulp, generate-md - build and dev tools.
Stars: ✭ 53 (+307.69%)
Mutual labels:  grunt
angular-compile
🆖 Angular Dynamic Compile - Convert strings to Angular components
Stars: ✭ 87 (+569.23%)
Mutual labels:  grunt

grunt-xmlpoke

Updates values in XML files based on XPath queries. Similar to the xmlpoke task in NAnt.

npm version Build Status

Getting Started

This plugin requires Grunt >=0.4.2

If you haven't used Grunt before, be sure to check out the Getting Started guide, as it explains how to create a Gruntfile as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:

npm install grunt-xmlpoke --save-dev

Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:

grunt.loadNpmTasks('grunt-xmlpoke');

The "xmlpoke" task

Overview

In your project's Gruntfile, add a section named xmlpoke to the data object passed into grunt.initConfig().

grunt.initConfig({
  xmlpoke: {
    updateTitle: {
      options: {
        xpath: '//title',
        value: 'The Good Parts'
      },
      files: {
        'dest.xml': 'src.xml'
      },
    },
  },
})

Options

options.xpath

Type: String Default value: ''

An xpath query to select one or more nodes in the source document.

options.value

Type: String or Function Default value: ''

A string value to which the value of any matched node is set.

You can also supply a function that returns the replacement value. The first argument supplied to the function will be the node on which the replacement is being made.

options.namespaces

Type: object Default value: {}

An object mapping between XML namespace prefixes and names (URIs). For example, { 'em': 'http://example.org/XML/em' }

options.valueType

Type: String Default value: 'text'

The text content of the node(s) will be set using options.value.

Setting to 'element' will replace the value of the node(s) with raw xml element(s) as defined in options.value. Setting to 'append' will append the raw xml element(s) as defined in options.value to the end of the selected node(s). Setting to 'remove' will remove the node(s) from the xml (options.value is ignored).

options.replacements

Type: Array Default value: undefined

An array of replacement options (i.e. objects with xpath and value properties)

Usage Examples

Basic Usage

In this example, the text content of an element is set to a static value. So if the testing.xml file has the content <abc></abd>, the generated result would be <abc>123</abc>.

grunt.initConfig({
  setTheNumber: {
    xmlpoke: {
      options: {
        xpath: '/abc',
        value: '123'
      },
      files: {
        'dest/basic_usage.xml': 'src/testing.xml',
      },
    },
  },
})

Attribute Example

In this example, the value of an attribute is cleared. So if the testing.xml file has the content <x y="999" />, the generated result in this case would be <x y="" />.

grunt.initConfig({
  xmlpoke: {
    updateAnAttribute: {
      options: {
        xpath: '/x/@y',
        value: ''
      },
      files: {
        'dest/attribute_example.xml': 'src/testing.xml',
      },
    },
  },
})

Element Example

In this example, an element is set as the child of an other element. So if the testing.xml file has the content <x><y /></x>, the generated result in this case would be <x><z /></x>.

grunt.initConfig({
  xmlpoke: {
    updateAnAttribute: {
      options: {
        xpath: '/x',
        value: '<z />',
        valueType: 'element'
      },
      files: {
        'dest/element_example.xml': 'src/testing.xml',
      },
    },
  },
})

Append Example

In this example, an element is added to another element. So if the testing.xml file has the content <x><y /></x>, the generated result in this case would be <x><y /><z /></x>.

grunt.initConfig({
  xmlpoke: {
    updateAnAttribute: {
      options: {
        xpath: '/x',
        value: '<z />',
        valueType: 'append'
      },
      files: {
        'dest/append_example.xml': 'src/testing.xml',
      },
    },
  },
})

Function Example

In this example, the value of an attribute is modified. So if the testing.xml file has the content <x y="abc" />, the generated result in this case would be <x y="ABC" />.

grunt.initConfig({
  xmlpoke: {
    upperCaseTheY: {
      options: {
        xpath: '/x/@y',
        value: function (node) { return node.value.toUpperCase(); }
      },
      files: {
        'dest/function_example.xml': 'src/testing.xml',
      },
    },
  },
})

Multiple XPath Queries

In this example, the same value is put intp multiple locations. So if the testing.xml file has the content <x y="999" />, the generated result in this case would be <x y="111">111</x>.

grunt.initConfig({
  xmlpoke: {
    updateAllTheThings: {
      options: {
        xpath: ['/x/@y','/x'],
        value: '111'
      },
      files: {
        'dest/multiple_xpath_queries.xml': 'src/testing.xml',
      },
    },
  },
})

Multiple Replacements

In this example, multiple replacements take place at once. So if the testing.xml file has the content <x y="999" />, the generated result in this case would be <x y="111">M</x>.

grunt.initConfig({
  xmlpoke: {
    updateACoupleOfThings: {
      options: {
        replacements: [{
          xpath: '/x/@y',
          value: '111'
        }, {
          xpath: '/x',
          value: 'M'
        }]
      },
      files: {
        'dest/multiple_replacements.xml': 'src/testing.xml',
      },
    },
  },
})

XML Namespace Example

In this example, the XML file contains namespaces (i.e. xmlns attributes). For example, an Apache Cordova config.xml file might look like this:

<?xml version='1.0' encoding='utf-8'?>
<widget id="io.cordova.hellocordova" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name>HelloCordova</name>
    <description>A sample Apache Cordova application that responds to the deviceready event.</description>
    <author email="[email protected]" href="http://cordova.io">Apache Cordova Team</author>
    <content src="index.html" />
    <plugin name="cordova-plugin-whitelist" spec="1" />
    <access origin="*" />
    <allow-intent href="http://*/*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="tel:*" />
    <allow-intent href="sms:*" />
    <allow-intent href="mailto:*" />
    <allow-intent href="geo:*" />
    <platform name="android">
        <allow-intent href="market:*" />
    </platform>
    <platform name="ios">
        <allow-intent href="itms:*" />
        <allow-intent href="itms-apps:*" />
    </platform>
    <cdv:custom-cordova-thing>old value</cdv:custom-cordova-thing>
</widget>

The xmlns:cdv attribute defines the namespace for the cdv prefix, but the xmlns attribute without a suffix defines the default namespace for that element and its descendants. Therefore, when targeting the <widget> element, your XPath expression will need to reference that namespace. Note, however, that the namespace does not affect attributes, only elements. In the example we define the unused cdv prefix for completeness, but it's not used in the XPath expression, so it's not required to be defined. Also, while it's simplest to keep the prefixes the same, it's not required for the prefix used in your XPath expression to match the prefix defined in the document (e.g. your XML may have an xmlns:cdv attribute, and your Grunt config could reference that same namespace URL with the prefix 'c').

grunt.initConfig({
  xmlpoke: {
    widget: {
      options: {
        namespaces: {
          'w': 'http://www.w3.org/ns/widgets',
          'cdv': 'http://cordova.apache.org/ns/1.0'
        },
        replacements: [{
            xpath: '/w:widget/@version',
            value: '0.2.1'
        },{
            xpath: '/w:widget/w:author',
            value: 'Someone Else'
        },{
            xpath: '/w:widget/w:author/@email',
            value: '[email protected]'
        },{
            xpath: '/w:widget/cdv:custom-cordova-thing',
            value: 'new value'
        }]
      },
      files: {
        'dest/config.xml': 'src/config.xml',
      },
    },
  },
})

Fail On Missing XPath

By default, if the provided XPath expression doesn't match any nodes, the task will silently continue. You can override this behavior by specifying failIfMissing in the options (either at the top level of the task, or in a sub-task), or within a single replacement.

grunt.initConfig({
  xmlpoke: {
    options: {
      failIfMissing: true
    },
    updateACoupleOfThings: {
      options: {
        replacements: [{
          xpath: '/x/@y',
          value: '111',
          failIfMissing: false
        }, {
          xpath: '/x',
          value: 'M'
        }]
      },
      files: {
        'dest/element_required_attribute_optional.xml': 'src/testing.xml',
      },
    },
  },
})

Contributing

In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using Grunt.

Release History

  • 0.1.0 — Initial release
  • 0.2.0 — Multiple replacements at once
  • 0.2.1 — Color filename when logged
  • 0.3.0 — Allow specifying replacement value as a function (Thanks @dimasty!)
  • 0.4.0 — Allow specifying namespaces (Thanks @j1mmie!)
  • 0.5.0 — Allow replacing with XML elements, not just text (Thanks @kraihn!)
  • 0.6.0 — Allow removing XML elements (Thanks @mradcliffe!)
  • 0.7.0 — Allow appending XML elements (Thanks @njtman!)
  • 0.8.0 — Add option to fail if XPath expression doesn't match any nodes (Thanks @omatrycy!)
  • 0.8.1 — Fix broken dependency (Thanks @hbogs!)
  • 0.8.2 — Update dependencies (Thanks @greenkeeperio!)
  • 0.8.3 — Update dependencies (Thanks @greenkeeperio!)
  • 0.9.0 — Support appending XML with namespaces (Thanks @sebbi08!)
  • 0.10.0 — Better error messages (Thanks @sebbi08!)
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].