0
<?xml version="1.0" encoding="utf-8" ?>
<xliff>
    <body>
        <trans-unit id="NFDBB2FA9-tu4" xml:space="preserve">
            <source xml:lang="en">He</source>
            <target xml:lang="id">He</target>
        </trans-unit>
        <trans-unit id="NFDBB2FA9-tu5" xml:space="preserve">
            <source xml:lang="en">She</source>
            <target xml:lang="id">She</target>
        </trans-unit>
    </body>
    <body>
        <trans-unit id="NFDBB2FA9-tu6" xml:space="preserve">
            <source xml:lang="en">They</source>
            <target xml:lang="id">They</target>
        </trans-unit>
        <trans-unit id="NFDBB2FA9-tu7" xml:space="preserve">
            <source xml:lang="en">We</source>
            <target xml:lang="id">We</target>
        </trans-unit>
    </body>
</xliff>

how do I modify value of <target> of trans-unit id="NFDBB2FA9-tu7" or any other?

done this but empty on the print_r and don't know what's next

$dom = new \DOMDocument();
$dom->load("my.xlf");
$root = $dom->documentElement;
$xliffBodies = $root->getElementsByTagName("body")->item(0);

foreach ($xliffBody as $body) {
    $el = $body->getElementsByTagName("trans-unit");
    print_r($el);
}

1 Answer 1

2

The code below is using a string representation of the original XML file (my.xlf) for convenience - change the loadXML for load to load your file.

If you use an XPath expression you can target these elements directly - though here I targeted the trans-unit node initially before selecting the child node - target

<?php

    $strxml='<?xml version="1.0" encoding="utf-8" ?>
<xliff>
    <body>
        <trans-unit id="NFDBB2FA9-tu4" xml:space="preserve">
            <source xml:lang="en">He</source>
            <target xml:lang="id">He</target>
        </trans-unit>
        <trans-unit id="NFDBB2FA9-tu5" xml:space="preserve">
            <source xml:lang="en">She</source>
            <target xml:lang="id">She</target>
        </trans-unit>
    </body>
    <body>
        <trans-unit id="NFDBB2FA9-tu6" xml:space="preserve">
            <source xml:lang="en">They</source>
            <target xml:lang="id">They</target>
        </trans-unit>
        <trans-unit id="NFDBB2FA9-tu7" xml:space="preserve">
            <source xml:lang="en">We</source>
            <target xml:lang="id">We</target>
        </trans-unit>
    </body>
</xliff>';

    $dom=new DOMDocument;
    $dom->loadXML($strxml);
    
    $xp=new DOMXPath($dom);
    $xp->registerNamespace('xml','http://www.example.com');
    
    $col=$xp->query( '//xliff/body/trans-unit' );
    if( $col && $col->length ){
        foreach( $col as $node ){
            $target=$xp->query('target',$node)->item(0);
            $target->nodeValue='banana';
        }
    }
    
    printf('<textarea cols=50 rows=10>%s</textarea>',$dom->saveXML());

?>

A simple edit - change the target value to the word banana yields:

Example output

The original snippet of XML is a little different from the actual XML in that there are namespace declarations which mean you need to adopt a slightly different approach. More Information on Namespaces

The default namespace needs to be used in the query, like so:

<?php

    $id='NFDBB2FA9-tu26';
    
    $file='my.xlf';

    $dom=new DOMDocument;
    $dom->load( $file );
    
    $xp=new DOMXPath( $dom );
    # We need to use this in the XPath query - this could be almost anything but best kept short!!
    $xp->registerNamespace('f','urn:oasis:names:tc:xliff:document:1.2');
    
    # Not essential to declare the following when simply querying against the default namespace
    $xp->registerNamespace('okp','okapi-framework:xliff-extensions');
    $xp->registerNamespace('its','http://www.w3.org/2005/11/its');
    $xp->registerNamespace('itsxlf','http://www.w3.org/ns/its-xliff/');
    $xp->registerNamespace('xml','http://www.example.com');
    
    # note how each portion of the XPath expression uses our namespace prefix..
    $col=$xp->query( '//f:xliff/f:file/f:body/f:trans-unit[@id="'.$id.'"]/f:target' );
    
    
    
    if( $col && $col->length ){
        foreach( $col as $node ){
            $node->nodeValue='Big Bold Brave Banana';
        }
    }
    
    printf('<textarea cols=180 rows=40>%s</textarea>',$dom->saveXML());

?>
Sign up to request clarification or add additional context in comments.

6 Comments

could it target a specific target inside a given <trans-unit id> ?
yes - you can be very specific wit hthe XPath expression. If you know an ID or a particular attribute you can build the Xpath expression to explicitly target that element
I'm reproducing on this but can't get it to work. xpather.com/HJhVshob . this is what I've done : pastebin.com/uEMMkC1s . it returns 0 on DOMNodeList
Perhaps a quick read of the PHP manual might help? Essentially your XPath expression is missing the initial // and does not use the default namespace in the XPath expression
on this: $node->nodeValue='Big Bold Brave Banana';. if I insert it as html code, e.g. $node->nodeValue='<some id="1">Big Bold Brave Banana'; . this is not encoded . how do I encode it?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.