Skip to content

XmlElement

Represents a parsed binary XML element from AndroidManifest.xml.

Overview

Android stores XML files (like AndroidManifest.xml) in a binary format. The XmlElement class provides access to the parsed structure.

typescript
import { Apk } from "node-apk";
import { XmlElement } from "node-apk";

const apk = new Apk("app.apk");
const manifest = await apk.getManifestInfo();

// Access raw XML
const raw = manifest.raw;

Properties

tag

typescript
readonly tag: string

The XML tag name.

Example

typescript
console.log(raw.tag);
// Output: "manifest" or "xml"

attributes

typescript
readonly attributes: Record<string, unknown>

The element's attributes as key-value pairs.

Example

typescript
const manifest = await apk.getManifestInfo();
const raw = manifest.raw;

console.log(raw.attributes["package"]);
console.log(raw.attributes["versionCode"]);

children

typescript
readonly children: Record<string, XmlElement[]>

Child elements grouped by tag name.

Example

typescript
const manifest = await apk.getManifestInfo();
const raw = manifest.raw;

// Access activities
const activities = raw.children["activity"] ?? [];
for (const activity of activities) {
  console.log(`Activity: ${activity.attributes["name"]}`);
}

// Access services
const services = raw.children["service"] ?? [];
for (const service of services) {
  console.log(`Service: ${service.attributes["name"]}`);
}

Methods

toString()

typescript
toString(): string

Returns a formatted JSON representation of the element.

Returns

string - JSON string with 4-space indentation.

Example

typescript
const manifest = await apk.getManifestInfo();
console.log(manifest.raw.toString());

Output:

json
{
    "tag": "xml",
    "attributes": {},
    "children": {
        "manifest": [
            {
                "tag": "manifest",
                "attributes": {
                    "package": "com.example.app",
                    "versionCode": 1,
                    "versionName": "1.0"
                },
                "children": {
                    "application": [...]
                }
            }
        ]
    }
}

Examples

Find All Activities

typescript
const manifest = await apk.getManifestInfo();

function findActivities(element: XmlElement): XmlElement[] {
  const activities = element.children["activity"] ?? [];
  
  // Recursively search children
  for (const child of Object.values(element.children).flat()) {
    activities.push(...findActivities(child));
  }
  
  return activities;
}

const allActivities = findActivities(manifest.raw);
console.log(`Found ${allActivities.length} activities`);

Find Intent Filters

typescript
const manifest = await apk.getManifestInfo();

function findIntentFilters(element: XmlElement): Array<{
  parent: string;
  actions: string[];
  categories: string[];
}> {
  const results: Array<{
    parent: string;
    actions: string[];
    categories: string[];
  }> = [];
  
  for (const [tag, elements] of Object.entries(element.children)) {
    for (const el of elements ?? []) {
      const filters = el.children["intent-filter"] ?? [];
      
      for (const filter of filters) {
        const actions = (filter.children["action"] ?? [])
          .map(a => a.attributes["name"] as string);
        const categories = (filter.children["category"] ?? [])
          .map(c => c.attributes["name"] as string);
        
        results.push({
          parent: el.attributes["name"] as string,
          actions,
          categories,
        });
      }
    }
  }
  
  return results;
}

const filters = findIntentFilters(manifest.raw);
for (const filter of filters) {
  console.log(`${filter.parent}:`);
  console.log(`  Actions: ${filter.actions.join(", ")}`);
  console.log(`  Categories: ${filter.categories.join(", ")}`);
}
typescript
function deepSearch(
  element: XmlElement,
  predicate: (el: XmlElement) => boolean
): XmlElement[] {
  const results: XmlElement[] = [];
  
  if (predicate(element)) {
    results.push(element);
  }
  
  for (const children of Object.values(element.children)) {
    for (const child of children ?? []) {
      results.push(...deepSearch(child, predicate));
    }
  }
  
  return results;
}

// Find all elements with exported="true"
const exported = deepSearch(manifest.raw, el => el.attributes["exported"] === true);
console.log(`Found ${exported.length} exported components`);

Extract Meta-Data

typescript
function getMetaData(element: XmlElement): Record<string, unknown> {
  const metaData: Record<string, unknown> = {};
  const metaElements = element.children["meta-data"] ?? [];
  
  for (const meta of metaElements) {
    const name = meta.attributes["name"] as string;
    const value = meta.attributes["value"];
    metaData[name] = value;
  }
  
  return metaData;
}

const manifest = await apk.getManifestInfo();
const appMeta = getMetaData(manifest.raw.children["application"]?.[0] ?? manifest.raw);
console.log("Meta-data:", appMeta);

Released under the MIT License.