【问题标题】:How to convert xml to valid json string如何将xml转换为有效的json字符串
【发布时间】:2022-08-04 18:37:53
【问题描述】:

我有一些 XML 我想输入到 api 端点,但是,我需要将 xml 转换为 json 有效字符串才能这样做。当我在线搜索将 xml 转换为 JSON 或“JSON 有效字符串”时,我发现解析器将 xml 转换为与 xml 具有相同结构的 json 对象。我想要一些不同的东西,我想将 xml 转换为一个字符串,该字符串将用作 json 字典中的单个值。

这意味着我需要将新行转换为 \"\\n\"。结果还需要通过 JSON lint 验证。 https://jsonlint.com

例如,假设我有以下快速代码:

import UIKit
import TableMVVM

class SubMenuChoice: NibView, HasViewModel {

    @IBOutlet var titleLabel: UILabel!
    @IBOutlet var detailsLabel: UILabel!
    @IBOutlet var viewToGradient: BottomLeftToTopRightGradient!

    var viewModel: ViewModel = .fallBack {
        didSet {
            self.titleLabel.text = viewModel.titleText
            self.detailsLabel.text = viewModel.detailText
            self.viewToGradient.layer.cornerRadius = 16
            self.viewToGradient.clipsToBounds = true
            self.viewToGradient.layer.borderColor = UIColor.white.cgColor
            self.viewToGradient.layer.borderWidth = 0.2
        }
    }
}

然后,我通过将新行换成文字回车将其转换为有效的单行 json 字符串。

{\"MyJSON\" : \"import UIKit\\nimport TableMVVM\\n\\nclass SubMenuChoice: NibView, HasViewModel {\\n\\n    @IBOutlet var titleLabel: UILabel!\\n    @IBOutlet var detailsLabel: UILabel!\\n    @IBOutlet var viewToGradient: BottomLeftToTopRightGradient!\\n\\n    var viewModel: ViewModel = .fallBack {\\n        didSet {\\n            self.titleLabel.text = viewModel.titleText\\n            self.detailsLabel.text = viewModel.detailText\\n            self.viewToGradient.layer.cornerRadius = 16\\n            self.viewToGradient.clipsToBounds = true\\n            self.viewToGradient.layer.borderColor = UIColor.white.cgColor\\n            self.viewToGradient.layer.borderWidth = 0.2\\n        }\\n    }\\n}\\n\"}

这是我需要转换为单行有效 json 字符串值的文本:

import UIKit
import TableMVVM

class SubMenuChoice: NibView, HasViewModel {

    @IBOutlet var titleLabel: UILabel!
    @IBOutlet var detailsLabel: UILabel!
    @IBOutlet var viewToGradient: BottomLeftToTopRightGradient!

    var viewModel: ViewModel = .fallBack {
        didSet {
            self.titleLabel.text = viewModel.titleText
            self.detailsLabel.text = viewModel.detailText
            self.viewToGradient.layer.cornerRadius = 16
            self.viewToGradient.clipsToBounds = true
            self.viewToGradient.layer.borderColor = UIColor.white.cgColor
            self.viewToGradient.layer.borderWidth = 0.2
        }
    }
}

extension SubMenuChoice {
    struct ViewModel: HasFallBack {
        let titleText: String
        let detailText: String

        static var fallBack: Self {
            .init(titleText: \"-\", detailText: \"-\")
        }
    }
}

///// Interface builder XML, .xib  /////
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVersion=\"19529\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\">
    <device id=\"retina6_1\" orientation=\"portrait\" appearance=\"light\"/>
    <dependencies>
        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"19519\"/>
        <capability name=\"Image references\" minToolsVersion=\"12.0\"/>
        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>
    </dependencies>
    <customFonts key=\"customFonts\">
        <array key=\"Inter-Regular.ttf\">
            <string>Inter-Regular</string>
        </array>
    </customFonts>
    <objects>
        <placeholder placeholderIdentifier=\"IBFilesOwner\" id=\"-1\" userLabel=\"File\'s Owner\" customClass=\"SubMenuChoice\" customModule=\"QRCodeTarot\" customModuleProvider=\"target\">
            <connections>
                <outlet property=\"detailsLabel\" destination=\"cA5-NT-4u9\" id=\"g9z-Bi-iPU\"/>
                <outlet property=\"titleLabel\" destination=\"Apr-Ou-WfJ\" id=\"cAU-7I-Tk1\"/>
                <outlet property=\"viewToGradient\" destination=\"UG4-zb-Meg\" id=\"cPu-gS-ndd\"/>
            </connections>
        </placeholder>
        <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"-2\" customClass=\"UIResponder\"/>
        <view contentMode=\"scaleToFill\" insetsLayoutMarginsFromSafeArea=\"NO\" id=\"iN0-l3-epB\">
            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"409\" height=\"127\"/>
            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>
            <subviews>
                <view contentMode=\"scaleToFill\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"UG4-zb-Meg\" customClass=\"BottomLeftToTopRightGradient\" customModule=\"QRCodeTarot\" customModuleProvider=\"target\">
                    <rect key=\"frame\" x=\"8\" y=\"8\" width=\"393\" height=\"111\"/>
                    <subviews>
                        <stackView opaque=\"NO\" contentMode=\"scaleToFill\" insetsLayoutMarginsFromSafeArea=\"NO\" alignment=\"center\" spacing=\"8\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"yCu-Vd-yGa\">
                            <rect key=\"frame\" x=\"20\" y=\"20\" width=\"353\" height=\"71\"/>
                            <subviews>
                                <stackView opaque=\"NO\" contentMode=\"scaleToFill\" axis=\"vertical\" alignment=\"top\" spacing=\"8\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"IbF-c7-i6X\">
                                    <rect key=\"frame\" x=\"0.0\" y=\"12\" width=\"323\" height=\"47.5\"/>
                                    <subviews>
                                        <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Game 1\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" numberOfLines=\"0\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Apr-Ou-WfJ\">
                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"60\" height=\"21\"/>
                                            <fontDescription key=\"fontDescription\" name=\"Inter-Regular\" family=\"Inter\" pointSize=\"17\"/>
                                            <color key=\"textColor\" white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>
                                            <nil key=\"highlightedColor\"/>
                                        </label>
                                        <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Short Description of game. \" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" numberOfLines=\"0\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"cA5-NT-4u9\">
                                            <rect key=\"frame\" x=\"0.0\" y=\"29\" width=\"194.5\" height=\"18.5\"/>
                                            <fontDescription key=\"fontDescription\" name=\"Inter-Regular\" family=\"Inter\" pointSize=\"15\"/>
                                            <color key=\"textColor\" red=\"0.70196078431372544\" green=\"0.70196078431372544\" blue=\"0.70196078431372544\" alpha=\"1\" colorSpace=\"calibratedRGB\"/>
                                            <nil key=\"highlightedColor\"/>
                                        </label>
                                    </subviews>
                                </stackView>
                                <imageView clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"scaleAspectFit\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"fmD-Uj-nrG\">
                                    <rect key=\"frame\" x=\"331\" y=\"25.5\" width=\"22\" height=\"20\"/>
                                    <color key=\"tintColor\" red=\"0.70196563010000002\" green=\"0.70195221900000004\" blue=\"0.70196127890000004\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"displayP3\"/>
                                    <constraints>
                                        <constraint firstAttribute=\"width\" constant=\"22\" id=\"5nL-F4-TDg\"/>
                                        <constraint firstAttribute=\"width\" secondItem=\"fmD-Uj-nrG\" secondAttribute=\"height\" id=\"TJa-x2-MQi\"/>
                                        <constraint firstAttribute=\"height\" constant=\"22\" id=\"zxE-9d-IP3\"/>
                                    </constraints>
                                    <imageReference key=\"image\" image=\"chevron.right\" catalog=\"system\" symbolScale=\"default\"/>
                                    <preferredSymbolConfiguration key=\"preferredSymbolConfiguration\" scale=\"default\" weight=\"semibold\"/>
                                </imageView>
                            </subviews>
                        </stackView>
                    </subviews>
                    <color key=\"backgroundColor\" red=\"0.094216383989999999\" green=\"0.097880952059999998\" blue=\"0.1137293801\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"displayP3\"/>
                    <accessibility key=\"accessibilityConfiguration\" hint=\"GradientRoundedbox\" identifier=\"GradientRoundedbox\" label=\"GradientRoundedbox\">
                        <bool key=\"isElement\" value=\"NO\"/>
                    </accessibility>
                    <constraints>
                        <constraint firstItem=\"yCu-Vd-yGa\" firstAttribute=\"top\" secondItem=\"UG4-zb-Meg\" secondAttribute=\"top\" constant=\"20\" id=\"3RX-6j-jOS\"/>
                        <constraint firstAttribute=\"trailing\" secondItem=\"yCu-Vd-yGa\" secondAttribute=\"trailing\" constant=\"20\" id=\"EO3-94-kqy\"/>
                        <constraint firstItem=\"yCu-Vd-yGa\" firstAttribute=\"leading\" secondItem=\"UG4-zb-Meg\" secondAttribute=\"leading\" constant=\"20\" id=\"ZqU-CK-TE2\"/>
                        <constraint firstAttribute=\"bottom\" secondItem=\"yCu-Vd-yGa\" secondAttribute=\"bottom\" constant=\"20\" id=\"j7q-UD-Mtj\"/>
                    </constraints>
                </view>
            </subviews>
            <color key=\"backgroundColor\" white=\"0.0\" alpha=\"0.0\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>
            <constraints>
                <constraint firstAttribute=\"trailing\" secondItem=\"UG4-zb-Meg\" secondAttribute=\"trailing\" constant=\"8\" id=\"2oh-y3-hqC\"/>
                <constraint firstItem=\"UG4-zb-Meg\" firstAttribute=\"leading\" secondItem=\"iN0-l3-epB\" secondAttribute=\"leading\" constant=\"8\" id=\"97v-Yx-mRr\"/>
                <constraint firstItem=\"UG4-zb-Meg\" firstAttribute=\"top\" secondItem=\"iN0-l3-epB\" secondAttribute=\"top\" constant=\"8\" id=\"eJq-NG-K3S\"/>
                <constraint firstAttribute=\"bottom\" secondItem=\"UG4-zb-Meg\" secondAttribute=\"bottom\" constant=\"8\" id=\"yw9-bW-Zza\"/>
            </constraints>
            <freeformSimulatedSizeMetrics key=\"simulatedDestinationMetrics\"/>
            <point key=\"canvasLocation\" x=\"128.2608695652174\" y=\"-143.63839285714286\"/>
        </view>
    </objects>
    <resources>
        <image name=\"chevron.right\" catalog=\"system\" width=\"96\" height=\"128\"/>
    </resources>
</document>


///// Unit tests  /////

Import XCTest

class SubMenuChoiceTests: XCTestCase { 
    
    
}

当我尝试用新行文字换出新行时,它会破坏 JSON linter。

我怀疑我不是第一个做这种事情的人,所以我希望有人知道将 xml 转换为有效 json 字符串的公式。请帮忙。谢谢你。

  • 您能否澄清“它破坏了 JSON linter”是什么意思? linter 会产生错误吗?如果是这样,它是什么错误?
  • 在 JSON 字符串中,除了换行符之外,还有更多字符需要转义。
  • jq -cn --rawfile xml foo.xml \'$xml\' 如果 jq 适用于您的环境。
  • @VadimBelyaev,我更新了提示。
  • 对此没有“公式”,因为有数百种将 XML 转换为 JSON 的方法,所有这些最终都以不同的方式表示相同的信息。如果您从特定的 XML 格式开始并想要生成特定的 JSON 格式,那么您通常需要“手动”编写一些转换逻辑 - 通常 XSLT 3.0 可以是一个方便的工具。

标签: ios json xml bash parsing


【解决方案1】:

您可以使用 github.com/mikefarah/yq 来做到这一点

yq -n --indent=0 '.MyJson = load_str("file.txt")' -o=json

这将创建一个新的 JSON 文档,其中加载了字符串内容。它会自动转义字符。

免责声明:我写了 yq

【讨论】:

    猜你喜欢
    • 2021-12-01
    • 2013-05-30
    • 2012-10-26
    • 2016-03-17
    • 1970-01-01
    • 2018-08-29
    • 1970-01-01
    • 1970-01-01
    • 2021-06-13
    相关资源
    最近更新 更多