PHP-XML: How do I modify text value of a given target
<?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
-
answered 2021-02-27 15:03
Professor Abronsius
The code below is using a string representation of the original XML file (
my.xlf
) for convenience - change theloadXML
forload
to load your file.If you use an
XPath
expression you can target these elements directly - though here I targeted thetrans-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 wordbanana
yields: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 NamespacesThe 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()); ?>