Автоматическое форматирование стилей отступов и самозакрывающихся тегов в списке свойств OS X / macOS XML - PullRequest
0 голосов
/ 29 апреля 2020

Я бы хотел автоматически отформатировать один или несколько файлов списка свойств OS X / macOS XML, чтобы использовать форматирование, как если бы вы запустили на них команду 'xmllint --format', за исключением того, что:

  • Я хочу, чтобы значения ключей аналогичным образом отступали на один уровень (два пробела) под их родительскими ключами.
  • Я не хочу, чтобы ключи со значениями '<data>' распределялись по нескольким строкам.

Я также хочу, чтобы у всех самозакрывающихся тегов были пробелы непосредственно перед закрывающей косой чертой. Какое XSLT (edit: или другое) преобразование я бы использовал для достижения этой цели?


В соответствии с запросом приведен минимальный рабочий пример (немного адаптированный из этого фрагмента документации Apple :)

  • До:
<?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&apos; 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&apos; Names</key>
    <array>
        <string>John</string>
        <string>Kyra</string>
    </array>
    <key>Pangram</key>
    <data>
    VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4gIA
    </data>
    <key>FollowingKeyDataLengthIsInsane</key>
    <true/>
    <key>&apos;Lorem Ipsum&apos; 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>
  • (Правка: что xmllint выводит, учитывая этот пример в файле с именем 'sample.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>

Это не то, что Я хочу, но я добавил это для полноты картины.)

  • После:
<?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&apos; 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&apos; Names</key>
    <array>
      <string>John</string>
      <string>Kyra</string>
    </array>
  <key>Pangram</key>
    <data>
      VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4gIA
    </data>
  <key>FollowingKeyDataLengthIsInsane</key>
    <true />
  <key>&apos;Lorem Ipsum&apos; 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>

1 Ответ

1 голос
/ 01 мая 2020

FWIW, вот как вы можете сделать отступ самостоятельно:

XSLT 1.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="'&#9;'"/>

<xsl:template match="*">
    <xsl:param name="indent" select="'&#10;'"/>
    <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>

Демо : https://xsltfiddle.liberty-development.net/pNmC4J6

...