如何用以换行符开头的属性和结束标记更正来美化XML



下面是我的XML输出:

<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0"
android:compileSdkVersion="23"
android:compileSdkVersionCodename="6.0-2438415"
package="com.mycompany.myapp"
platformBuildVersionCode="23"
platformBuildVersionName="6.0-2438415"
>
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="28"
>
</uses-sdk>
<!-- Read the contents of your shared storage -->
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
>
</uses-permission>
<!-- Modify or delete the contents of your shared storage -->
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
>
</uses-permission>
<application
android:theme="@7F1001D3"
android:label="@7F0F001B"
android:icon="@7F0D0000"
android:allowBackup="false"
android:supportsRtl="true"
android:roundIcon="@7F0D0001"
android:appComponentFactory="androidx.core.app.CoreComponentFactory"
>
<activity
android:name="com.mycompany.myapp.MainActivity"
android:configChanges="screenSize|orientation"
>
<intent-filter
>
<action
android:name="android.intent.action.MAIN"
>
</action>
<category
android:name="android.intent.category.LAUNCHER"
>
</category>
</intent-filter>
</activity>
</application>
</manifest>

正如您所看到的,它已经缩进,标记中的每个属性都以换行符开始,但它有奇怪的结束标记,例如:

<tag
prefix:name="str"
>
</tag>

或:

<tag
prefix:name="str1"
prefix:name2="str2"
>
</tag>

而不是:

<tag prefix:name="str" />

或:

<tag
prefix:name="str1"
prefix:name2="str2" />

我的问题是,如何美化XML,使标记中的每个属性都以换行符开始(除非标记中只有一个属性(,结束标记更正而不省略注释?在这里你可以看到我想要的输出:

<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0"
android:compileSdkVersion="23"
android:compileSdkVersionCodename="6.0-2438415"
package="com.mycompany.myapp"
platformBuildVersionCode="23"
platformBuildVersionName="6.0-2438415">
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="28" />
<!-- Read the contents of your shared storage -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- Modify or delete the contents of your shared storage -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:theme="@7F1001D3"
android:label="@7F0F001B"
android:icon="@7F0D0000"
android:allowBackup="false"
android:supportsRtl="true"
android:roundIcon="@7F0D0001"
android:appComponentFactory="androidx.core.app.CoreComponentFactory">
<activity
android:name="com.mycompany.myapp.MainActivity"
android:configChanges="screenSize|orientation">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

尝试使用各种pretifier,如Java的transformer、Apache Xerces的XML Serializer等。

Java的transformer无法更正结束标记。然而,ApacheXerces会更正结束标记,注释不会省略,但标记中的每个属性都不会以换行符开头。

或者,如果输出已经缩进,我可以尝试在字符串级别更正结束标记?

XML总是以相同的格式输出。

每个XML压头/格式化程序都有自己的方法,您唯一的选择是(a(尝试所有方法,直到找到符合您个人偏好的方法,或者(b(编写自己的方法。

Saxon的序列化程序(注意:我的产品(可能比大多数程序更具可定制性。但更高级的功能只出现在商业版中。

下面是我所做的:我已经为我的XML输出程序编写了基于正则表达式替换的XML pretifier。以下是代码(使用Apache Commons IO将字符串写入文件(:

private static void prettyPrint(File in) throws Throwable {
String file = new String(Files.readAllBytes(Paths.get(in.toString())));
Pattern p = Pattern.compile("\s+>\s+</.+>");
Matcher m = p.matcher(file);
StringBuffer sb = new StringBuffer();
while (m.find()) {
m.appendReplacement(sb, " />");
}
m.appendTail(sb);
FileUtils.writeStringToFile(in, sb.toString());
prettyPrint2(in);
}

private static void prettyPrint2(File in) throws Throwable {
String file = new String(Files.readAllBytes(Paths.get(in.toString())));
Pattern p = Pattern.compile("\s+>");
Matcher m = p.matcher(file);
StringBuffer sb = new StringBuffer();
while (m.find()) {
m.appendReplacement(sb, ">");
}
m.appendTail(sb);
FileUtils.writeStringToFile(in, sb.toString());
}

注意\s+>\s+</.+>图案它会转换这个

>
</foo>

到简化的结束标签:/>像这样:

<foo
bar="value1"
baz="value2" />

\s+>模式无理由校正此处的浮动>

<foo1
bar="value1"
baz="value2"
>
<foo2
bar="value1"
baz="value2"
>
</foo2>
</foo1>

去他的家:

<foo1
bar="value1"
baz="value2">
<foo2
bar="value1"
baz="value2">
</foo2>
</foo1>

将这两个正则表达式组合在一起,我得到了我想要的结果:

<foo1
bar="value1"
baz="value2">
<foo2
bar="value1"
baz="value2" />
</foo1>

工作起来很有魅力。也感谢所有帮助我的人。很高兴听到你的意见。

最新更新