使用xslt重新格式化xml文件并保留精确的格式


Reformat xml file using xslt and retain exact formatting

我有一个xml文件,需要以特定的方式格式化以确保可读性。

源XML

<?xml version="1.0" encoding="UTF-8"?>
<facility>
 <attributes>
   <id>1</id>
   <name>Facility Name</name>
   <coordinate>Lat,Long</coordinate>
   <projection>mercator</projection>
   <units>imperial</units>
   <showcart>yes</showcart>
   <shotplanner>yes</shotplanner>
   <sound>on</sound>
   <gfbkgcolor>#ff0000</gfbkgcolor>
   <gftxtcolor>#ffffff</gftxtcolor>
   <gcbkgcolor>#ffffff</gcbkgcolor>
   <gctxtcolor>#000000</gctxtcolor>
 </attributes>
</facility>

预期输出

<facility name="Facility Name" id="1" 
          coordinate="Lat,Long" projection="mercator" 
          units="imperial" showcart="yes" shotplanner="yes" 
          sound="on" gfbkgcolor="#ff0000" gftxtcolor="#ffffff" 
          gcbkgcolor="#ffffff">
</facility>

我有一个复杂的xml文件,但这正是我想要做的。

XSL模板

<?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"/>
<xsl:template match="/">
    <xsl:for-each select="facility/attributes">
        <facility id="{id}" name="{name}" 
                  coordinate="{coordinate}">
        </facility>
         <xsl:text>&#xA;</xsl:text>
        <test>"hello"</test>
   </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

使用这个<xsl:text>&#xA;</xsl:text>似乎抛出了一个错误,并且不显示输出xml。

  1. 使用xsl在某些属性后可以换行吗
  2. 我可以在给定元素中的子元素之间换行吗(这样它们就可以按逻辑分组)

我正在通过php形成上面的xml。一旦我有了xml,我希望它的格式如上所述。我可以使用php字符串来完成,但这是一个巨大的文件,这样做会很乏味。xsl可以用来解决这个问题吗?

任何关于如何实现这一目标的建议都将不胜感激。Thx

我不知道有什么XML序列化程序(基于XSLT或其他)可以让您对一组属性的格式进行这种级别的控制,尽管您可能可以通过利用xsl:output上的Saxon:attribute顺序和Saxon:line-length属性来接近Saxon:http://www.saxonica.com/documentation/index.html#!扩展/输出附加项/序列化参数。

目前还不清楚您当前的代码为什么会抛出错误,但由于您还没有告诉我们错误是什么,我不会试图回答这部分问题。

由于PHP是一种通用语言,并且配备了XSLT1.0处理器,您可以在一个脚本中处理操作、xml转换和文本格式化:

XSLT脚本(外部保存以在下面加载,或使用loadXML()作为嵌入字符串添加)

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
  <!-- Identity Transform -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="attributes/*"/>
    </xsl:copy>
  </xsl:template>  
  <!-- Migrate Nodes to Attributes -->
  <xsl:template match="attributes/*">    
      <xsl:attribute name="{name()}">
        <xsl:value-of select="."/>
      </xsl:attribute>
  </xsl:template>
</xsl:transform>

PHP编写脚本

<?php
// Load the XML source and XSLT file
$doc = new DOMDocument();
$doc->load('Source.xml');
$xsl = new DOMDocument;
$xsl->load('XSLTScript.xsl');
// Configure the processor
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl); 
// Transform XML source
$newXml = $proc->transformToXML($doc);
// Add line breaks, tabs, and spaces between attributes to output string
$newXml = str_replace("coordinate", "'n't't  coordinate", $newXml);
$newXml = str_replace("units", "'n't't  units", $newXml);
$newXml = str_replace("sound", "'n't't  sound", $newXml);
$newXml = str_replace("gcbkgcolor", "'n't't  gcbkgcolor", $newXml);
$newXml = str_replace("/>", ">'n</facility>", $newXml);
echo $newXml;
// Save output to file
$xmlfile = 'Output.xml';
file_put_contents($xmlfile, $newXml);
?>

输出

<?xml version="1.0" encoding="UTF-8"?>
<facility id="1" name="Facility Name" 
          coordinate="Lat,Long" projection="mercator" 
          units="imperial" showcart="yes" shotplanner="yes" 
          sound="on" gfbkgcolor="#ff0000" gftxtcolor="#ffffff" 
          gcbkgcolor="#ffffff" gctxtcolor="#000000">
</facility>

<?php
public function writeToXml(){
		$data = array(
			"id"          => 15,
			"name"        => "Facility Name",
			"coordinate"  => "Lat,lon",
			"projection"  => "mercator",
			"units"       => "imperial",
			"showcart"    => "yes",
			"shotplanner" => "yes",
			"sound"       => "on",
			"gfbkgcolor"  => "#ff0000",
			"gftxtcolor"  => "#ffffff",
			"gcbkgcolor"  => "#ffffff",
			"gctxtcolor"  => "#000000",
			"gbbkgcolor"  => "#0000ff",
			"gbtxtcolor"  => "#ffffff"
		);
    // Inserts a new line with a specified indent
	function insertNewLine($indent = 0){
		$line = "'n";
		$line .= str_repeat("'t", $indent);
		return $line;
	}
    
    // Formats a given string with a trailing space
	function formatString($string) {
		$data = "'"" . $string . "'" ";
		return $data;
	}
	$facility = "<?xml version='"1.0'" encoding='"utf-8'"?>";
	$facility .= insertNewLine();
	$facility .= "<facility name=" . formatString($data['name']);
	$facility .= "coordinate=" . formatString($data["coordinate"]);
	$facility .= insertNewLine(1);
	$facility .= "projection=" . formatString($data['projection']);
	$facility .= "units=" . formatString($data['units']);
	$facility .= "showcart=" . formatString($data['showcart']);
	$facility .= "shotplanner=" . formatString($data['shotplanner']);
	$facility .= "sound=" . formatString($data['sound']);
	$facility .= insertNewLine(1);
	$facility .= "gfbkgcolor=" . formatString($data['gfbkgcolor']);
	$facility .= "gftxtcolor=" . formatString($data['gftxtcolor']);
	$facility .= insertNewLine(1);
	$facility .= "gcbkgcolor=" . formatString($data['gcbkgcolor']);
	$facility .= "gctxtcolor=" . formatString($data['gctxtcolor']);
	$facility .= "/>";
	$myfile = fopen('application/packages/myfile.txt', 'w+');
	fwrite($myfile, $facility);
	fclose($myfile);
	// echo $facility;
});