自动格式化OS X/macOS XML属性列表';s缩进和自动关闭标记样式
我想自动格式化一个或多个OS X/macOS XML属性列表文件,以使用类似于在其上运行“自动格式化OS X/macOS XML属性列表';s缩进和自动关闭标记样式,xml,xslt,formatting,plist,xmllint,Xml,Xslt,Formatting,Plist,Xmllint,我想自动格式化一个或多个OS X/macOS XML属性列表文件,以使用类似于在其上运行“xmllint--format”的格式,除了: 我希望关键点的值在其父关键点下同样缩进一级(两个空格) 我不希望具有“”值的键跨多行拆分 我还希望所有的自动关闭标记在其关闭斜杠之前都有空格。我将使用什么XSLT(编辑:或其他)转换来实现这一点 根据要求,这里是一个最简单的工作示例(稍微改编自:) 之前: 这不是我想要的,但为了完整起见,我添加了它。) 之后: 出生年份 1965 宠物;名字
xmllint--format
”的格式,除了:
- 我希望关键点的值在其父关键点下同样缩进一级(两个空格)李>
- 我不希望具有“
”值的键跨多行拆分李>
根据要求,这里是一个最简单的工作示例(稍微改编自:)
- 之前:
- 之后:
出生年份
1965
宠物;名字
图画
PEKBpYGlmYFCPA==
出生城市
斯普林菲尔德
名称
无名氏
儿童'名字
约翰
凯拉
盘古
VGHLIHF1 WnRigjYB3DUIGZVECbqDW1WCYBVDMVyIhrozSBSYXP5IGRVZY4GIA
这太疯狂了
&载脂蛋白;Lorem Ipsum'示例文本
TG9YZW0GAXBZDW0GZG9SB3IGC2L0IGFTZXQSignVBNNLY3RLDHVYIGFKAXBPC2NPCBMCGZWXPDCWG
C2VKIGRVIGVVPDXNTB2QGDGVTCG9YIGULY2LKAWR1BNQGDXQGBGFIB3JLIGV0IGRVBG9YZSBTYWDU
YSBHBGLXDWEUIFV0IGVUAW0GYWQGBWLUAW0GDMVUAWFTLCBXDWLZIG5VC3RYDWQGZHLCMNPDGF0
AW9UIHVSBGFTY28GBGFIB3JPCYBUAXNPIHV0IGFSAXF1AXAGZGGZWEGY29TBW9KBYBJB25ZZXF1
yxquier1axmgyxv0zsbpcnvyzsbkb2xvcibpibyzxbyzwhlbmrlcml0igluihzvbhvwdgf0zsb2
ZWxPDCBLC3NLIGNPBGX1BSBKB2xVCMUGZXUGZNVNAWF0IG51BGXHIHBHCMLHLHDHVYLIBFEGNLCHRL
DXIGC2LUDCBVY2NHZWNHCBJDXBPZGF0YXQGBM9UIHBYB2LKZW50LCBZDW50IGLUIGGN1HBHIHF1
ASBVZMZPY2LHIGRLC2VYDW50IG1VBGXPDCBHBMLTIGLKIGVZDBSYWJVCNVTLGPDDXJHYML0DXIG
CHJLDGL1BSB0AW5JAWR1BNQGBGFJDXMUIE51BGXHIGDYXZPZGEGB3JJASBHIG9KAW8UIE51BGXH
BSB2YXJPDXMSIHR1CNBPCYBLDCBJB21TB2RVIHBOYXJLDHJHLCBC3QGZXJVCYBIAWJLBMR1BSBL
bgl0lcbuzwmgbhvjdhvzig1hz25higzlbglzihnvbgxpy2l0dwrpbibtyxvyaxmuideludgvnzxig
aW4gbWF1cmlzIGV1IG5pYmggZXVpc21vZCBncmF2aWRhLiBEdWlzIGFjIHRlbGx1cyBldCByaXN1
Cyb2DWxWdxRhdgugdmVoawn1BGuerVBMjigxVyM9YDGlZiHjPC3VzigeGzWxPDC4GRXRPyW0G
DGVTCG9Ylibvdcb1bgxhbwnvcnblciwgbglndwhigv1hrlbxbvcibjb25ndwusigvyb3mgzxn0
IGV1aXNtb2QgdHVycGlzLCBpZCB0aW5jaWR1bnQgc2FwaWVuIHJpc3VzIGEgcXVhbS4gTWFlY2Vu
yxmgzmvybwvudhvignvbnnlcxvhdcbtas4grg9uzwmgzmvybwvudhvlibqzwxszw50zxnxdwug
BWFSzxN1YWRHIG51BGXHIGEGBWKUIER1AxMGC2FWVuIHNLBSWgYWxPcxVLDCBUZWMSIGNVBW1V
ZG8GZWDLDCWGY29UC2VxDWF0IHF1AXMSIG5LCXVLIBGLXDWFTIGZHDWNPYNVZLCBLBGL0IHV0
IGRPY3R1BSBHBGLXLXDV0LCBMZWxPcybuaxNSIGFkaxBpc2nPMCGC2FWAWULCBZWQGBWFSzXN1
YWRhIGRpYW0gbGFjdXMgZWdldCBlcmF0LiBDcmFzIG1vbGxpcyBzY2VsZXJpc3F1ZSBudW5jLiBO
dWxsYW0gYXJjdS4gQWxpcXVhbSBjb25zZXF1YXQuIEN1cmFiaXR1ciBhdWd1ZSBsb3JlbSwgZGFw
AWJ1CYBXDWLZLCBW9YZWV0IGV0LCBWCMV0AXVTIGFJLCBUAXNPLIBBZW5LYW4GBWFNBMEGBMLZ
BCWGBW9SBGLZIHF1AxMSIG1VBGVZDGLLIGV1LCBMZxVNAWF0IGLULCVCMNPLIBIBIBOYWMGAGFI
AXRHC3NLIHBSYXRLYSBKAW0DW1ZDC4=
FWIW,以下是您自己缩进输出的方法:
XSLT1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="no"/>
<xsl:strip-space elements="*"/>
<xsl:param name="indent-unit" select="'	'"/>
<xsl:template match="*">
<xsl:param name="indent" select="' '"/>
<xsl:value-of select="$indent"/>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates>
<xsl:with-param name="indent" select="concat($indent, $indent-unit)"/>
</xsl:apply-templates>
</xsl:copy>
<xsl:if test="not(following-sibling::*)">
<xsl:value-of select="substring($indent, 1, string-length($indent) - string-length($indent-unit))"/>
</xsl:if>
</xsl:template>
<xsl:template match="*[preceding-sibling::*[1][self::key]]">
<xsl:param name="indent"/>
<xsl:value-of select="concat($indent, $indent-unit)"/>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates>
<xsl:with-param name="indent" select="concat($indent, $indent-unit, $indent-unit)"/>
</xsl:apply-templates>
</xsl:copy>
<xsl:if test="not(following-sibling::*)">
<xsl:value-of select="substring($indent, 1, string-length($indent) - string-length($indent-unit))"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
演示:请添加输入和预期输出的示例-请参阅:。我现在添加了一个示例。恐怕这些都不可行或实用。1.键不是其值的父项,而是兄弟项。即使您设法使一个值相对于其键缩进,也将消除该值与其子项之间的缩进差异。除非你自己做缩进,这是可能的,但工作量很大。2.XSLT不会跨多行分割数据(除非您明确指示并为其构建机制);如果不希望换行,请调整查看应用程序的首选项。我不知道如何在元素名中添加空格(这是您最后一个请求的结果)。元素名称不能包含空格字符。如果您试图添加它,您将得到一个错误,或者处理器将忽略它。您可以通过调整XSLT处理器的设置来实现这一点,但不能通过样式表。我不知道其他的工具。重新分割数据,我的意思是,默认情况下,文本节点的传递是不变的。关于元素之间的空白,有各种各样的选择,我在这里不一一列举。非常感谢!这比手工插入缩进要容易得多。嗯,我认为我的本地版本的“
xmllint
”和“xsltproc
”有缺陷。我现在只使用该web链接,因为它可以工作,以后再处理本地包管理……它对我使用xsltproc
很好,但有一个例外:XML声明和根元素之间有一个空行。macOS 10.13.6中包含的版本:“使用libxml 20904、libxslt 10129和libexslt 817 xsltproc是针对libxml 20904编译的,libxslt 10129和libexslt 817 libxslt 10129是针对libxml 20904编译的,libexslt 817 libxslt 10129是针对libxml 20904编译的”如果您传递一个名为indent
的参数,它将被忽略,因为没有具有该名称的全局参数。另外,indent
不用于确定要缩进的行。它用于确定缩进量-IOW,即当前元素的开始标记之前要输出的字符串。由于处理沿着树递归,并且每一代都会向它传递给其子代的缩进中添加一个缩进单元,因此会得到一个属性缩进树(w
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Year Of Birth</key>
<integer>1965</integer>
<key>Pets' Names</key>
<array/>
<key>Picture</key>
<data>
PEKBpYGlmYFCPA==
</data>
<key>City of Birth</key>
<string>Springfield</string>
<key>Name</key>
<string>John Doe</string>
<key>Kids' Names</key>
<array>
<string>John</string>
<string>Kyra</string>
</array>
<key>Pangram</key>
<data>
VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4gIA
</data>
<key>FollowingKeyDataLengthIsInsane</key>
<true/>
<key>'Lorem Ipsum' Sample Text</key>
<data>
TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdCwg
c2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWdu
YSBhbGlxdWEuIFV0IGVuaW0gYWQgbWluaW0gdmVuaWFtLCBxdWlzIG5vc3RydWQgZXhlcmNpdGF0
aW9uIHVsbGFtY28gbGFib3JpcyBuaXNpIHV0IGFsaXF1aXAgZXggZWEgY29tbW9kbyBjb25zZXF1
YXQuIER1aXMgYXV0ZSBpcnVyZSBkb2xvciBpbiByZXByZWhlbmRlcml0IGluIHZvbHVwdGF0ZSB2
ZWxpdCBlc3NlIGNpbGx1bSBkb2xvcmUgZXUgZnVnaWF0IG51bGxhIHBhcmlhdHVyLiBFeGNlcHRl
dXIgc2ludCBvY2NhZWNhdCBjdXBpZGF0YXQgbm9uIHByb2lkZW50LCBzdW50IGluIGN1bHBhIHF1
aSBvZmZpY2lhIGRlc2VydW50IG1vbGxpdCBhbmltIGlkIGVzdCBsYWJvcnVtLgpDdXJhYml0dXIg
cHJldGl1bSB0aW5jaWR1bnQgbGFjdXMuIE51bGxhIGdyYXZpZGEgb3JjaSBhIG9kaW8uIE51bGxh
bSB2YXJpdXMsIHR1cnBpcyBldCBjb21tb2RvIHBoYXJldHJhLCBlc3QgZXJvcyBiaWJlbmR1bSBl
bGl0LCBuZWMgbHVjdHVzIG1hZ25hIGZlbGlzIHNvbGxpY2l0dWRpbiBtYXVyaXMuIEludGVnZXIg
aW4gbWF1cmlzIGV1IG5pYmggZXVpc21vZCBncmF2aWRhLiBEdWlzIGFjIHRlbGx1cyBldCByaXN1
cyB2dWxwdXRhdGUgdmVoaWN1bGEuIERvbmVjIGxvYm9ydGlzIHJpc3VzIGEgZWxpdC4gRXRpYW0g
dGVtcG9yLiBVdCB1bGxhbWNvcnBlciwgbGlndWxhIGV1IHRlbXBvciBjb25ndWUsIGVyb3MgZXN0
IGV1aXNtb2QgdHVycGlzLCBpZCB0aW5jaWR1bnQgc2FwaWVuIHJpc3VzIGEgcXVhbS4gTWFlY2Vu
YXMgZmVybWVudHVtIGNvbnNlcXVhdCBtaS4gRG9uZWMgZmVybWVudHVtLiBQZWxsZW50ZXNxdWUg
bWFsZXN1YWRhIG51bGxhIGEgbWkuIER1aXMgc2FwaWVuIHNlbSwgYWxpcXVldCBuZWMsIGNvbW1v
ZG8gZWdldCwgY29uc2VxdWF0IHF1aXMsIG5lcXVlLiBBbGlxdWFtIGZhdWNpYnVzLCBlbGl0IHV0
IGRpY3R1bSBhbGlxdWV0LCBmZWxpcyBuaXNsIGFkaXBpc2Npbmcgc2FwaWVuLCBzZWQgbWFsZXN1
YWRhIGRpYW0gbGFjdXMgZWdldCBlcmF0LiBDcmFzIG1vbGxpcyBzY2VsZXJpc3F1ZSBudW5jLiBO
dWxsYW0gYXJjdS4gQWxpcXVhbSBjb25zZXF1YXQuIEN1cmFiaXR1ciBhdWd1ZSBsb3JlbSwgZGFw
aWJ1cyBxdWlzLCBsYW9yZWV0IGV0LCBwcmV0aXVtIGFjLCBuaXNpLiBBZW5lYW4gbWFnbmEgbmlz
bCwgbW9sbGlzIHF1aXMsIG1vbGVzdGllIGV1LCBmZXVnaWF0IGluLCBvcmNpLiBJbiBoYWMgaGFi
aXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4=
</data>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Year Of Birth</key>
<integer>1965</integer>
<key>Pets' Names</key>
<array />
<key>Picture</key>
<data>
PEKBpYGlmYFCPA==
</data>
<key>City of Birth</key>
<string>Springfield</string>
<key>Name</key>
<string>John Doe</string>
<key>Kids' Names</key>
<array>
<string>John</string>
<string>Kyra</string>
</array>
<key>Pangram</key>
<data>
VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4gIA
</data>
<key>FollowingKeyDataLengthIsInsane</key>
<true />
<key>'Lorem Ipsum' Sample Text</key>
<data>
TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdCwg
c2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWdu
YSBhbGlxdWEuIFV0IGVuaW0gYWQgbWluaW0gdmVuaWFtLCBxdWlzIG5vc3RydWQgZXhlcmNpdGF0
aW9uIHVsbGFtY28gbGFib3JpcyBuaXNpIHV0IGFsaXF1aXAgZXggZWEgY29tbW9kbyBjb25zZXF1
YXQuIER1aXMgYXV0ZSBpcnVyZSBkb2xvciBpbiByZXByZWhlbmRlcml0IGluIHZvbHVwdGF0ZSB2
ZWxpdCBlc3NlIGNpbGx1bSBkb2xvcmUgZXUgZnVnaWF0IG51bGxhIHBhcmlhdHVyLiBFeGNlcHRl
dXIgc2ludCBvY2NhZWNhdCBjdXBpZGF0YXQgbm9uIHByb2lkZW50LCBzdW50IGluIGN1bHBhIHF1
aSBvZmZpY2lhIGRlc2VydW50IG1vbGxpdCBhbmltIGlkIGVzdCBsYWJvcnVtLgpDdXJhYml0dXIg
cHJldGl1bSB0aW5jaWR1bnQgbGFjdXMuIE51bGxhIGdyYXZpZGEgb3JjaSBhIG9kaW8uIE51bGxh
bSB2YXJpdXMsIHR1cnBpcyBldCBjb21tb2RvIHBoYXJldHJhLCBlc3QgZXJvcyBiaWJlbmR1bSBl
bGl0LCBuZWMgbHVjdHVzIG1hZ25hIGZlbGlzIHNvbGxpY2l0dWRpbiBtYXVyaXMuIEludGVnZXIg
aW4gbWF1cmlzIGV1IG5pYmggZXVpc21vZCBncmF2aWRhLiBEdWlzIGFjIHRlbGx1cyBldCByaXN1
cyB2dWxwdXRhdGUgdmVoaWN1bGEuIERvbmVjIGxvYm9ydGlzIHJpc3VzIGEgZWxpdC4gRXRpYW0g
dGVtcG9yLiBVdCB1bGxhbWNvcnBlciwgbGlndWxhIGV1IHRlbXBvciBjb25ndWUsIGVyb3MgZXN0
IGV1aXNtb2QgdHVycGlzLCBpZCB0aW5jaWR1bnQgc2FwaWVuIHJpc3VzIGEgcXVhbS4gTWFlY2Vu
YXMgZmVybWVudHVtIGNvbnNlcXVhdCBtaS4gRG9uZWMgZmVybWVudHVtLiBQZWxsZW50ZXNxdWUg
bWFsZXN1YWRhIG51bGxhIGEgbWkuIER1aXMgc2FwaWVuIHNlbSwgYWxpcXVldCBuZWMsIGNvbW1v
ZG8gZWdldCwgY29uc2VxdWF0IHF1aXMsIG5lcXVlLiBBbGlxdWFtIGZhdWNpYnVzLCBlbGl0IHV0
IGRpY3R1bSBhbGlxdWV0LCBmZWxpcyBuaXNsIGFkaXBpc2Npbmcgc2FwaWVuLCBzZWQgbWFsZXN1
YWRhIGRpYW0gbGFjdXMgZWdldCBlcmF0LiBDcmFzIG1vbGxpcyBzY2VsZXJpc3F1ZSBudW5jLiBO
dWxsYW0gYXJjdS4gQWxpcXVhbSBjb25zZXF1YXQuIEN1cmFiaXR1ciBhdWd1ZSBsb3JlbSwgZGFw
aWJ1cyBxdWlzLCBsYW9yZWV0IGV0LCBwcmV0aXVtIGFjLCBuaXNpLiBBZW5lYW4gbWFnbmEgbmlz
bCwgbW9sbGlzIHF1aXMsIG1vbGVzdGllIGV1LCBmZXVnaWF0IGluLCBvcmNpLiBJbiBoYWMgaGFi
aXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4=
</data>
</dict>
</plist>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="no"/>
<xsl:strip-space elements="*"/>
<xsl:param name="indent-unit" select="'	'"/>
<xsl:template match="*">
<xsl:param name="indent" select="' '"/>
<xsl:value-of select="$indent"/>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates>
<xsl:with-param name="indent" select="concat($indent, $indent-unit)"/>
</xsl:apply-templates>
</xsl:copy>
<xsl:if test="not(following-sibling::*)">
<xsl:value-of select="substring($indent, 1, string-length($indent) - string-length($indent-unit))"/>
</xsl:if>
</xsl:template>
<xsl:template match="*[preceding-sibling::*[1][self::key]]">
<xsl:param name="indent"/>
<xsl:value-of select="concat($indent, $indent-unit)"/>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates>
<xsl:with-param name="indent" select="concat($indent, $indent-unit, $indent-unit)"/>
</xsl:apply-templates>
</xsl:copy>
<xsl:if test="not(following-sibling::*)">
<xsl:value-of select="substring($indent, 1, string-length($indent) - string-length($indent-unit))"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>